xref: /isa-l/igzip/igzip_file_perf.c (revision 55fbfabfc60f1002bc8133b730a59f6abd22cfce)
1 /**********************************************************************
2   Copyright(c) 2011-2016 Intel Corporation All rights reserved.
3 
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions
6   are met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above copyright
10       notice, this list of conditions and the following disclaimer in
11       the documentation and/or other materials provided with the
12       distribution.
13     * Neither the name of Intel Corporation nor the names of its
14       contributors may be used to endorse or promote products derived
15       from this software without specific prior written permission.
16 
17   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
29 
30 #define _FILE_OFFSET_BITS 64
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <assert.h>
34 #include <string.h>
35 #include <getopt.h>
36 #include "igzip_lib.h"
37 #include "test.h"
38 
39 #define BUF_SIZE 1024
40 
41 int level_size_buf[10] = {
42 #ifdef ISAL_DEF_LVL0_DEFAULT
43         ISAL_DEF_LVL0_DEFAULT,
44 #else
45         0,
46 #endif
47 #ifdef ISAL_DEF_LVL1_DEFAULT
48         ISAL_DEF_LVL1_DEFAULT,
49 #else
50         0,
51 #endif
52 #ifdef ISAL_DEF_LVL2_DEFAULT
53         ISAL_DEF_LVL2_DEFAULT,
54 #else
55         0,
56 #endif
57 #ifdef ISAL_DEF_LVL3_DEFAULT
58         ISAL_DEF_LVL3_DEFAULT,
59 #else
60         0,
61 #endif
62 #ifdef ISAL_DEF_LVL4_DEFAULT
63         ISAL_DEF_LVL4_DEFAULT,
64 #else
65         0,
66 #endif
67 #ifdef ISAL_DEF_LVL5_DEFAULT
68         ISAL_DEF_LVL5_DEFAULT,
69 #else
70         0,
71 #endif
72 #ifdef ISAL_DEF_LVL6_DEFAULT
73         ISAL_DEF_LVL6_DEFAULT,
74 #else
75         0,
76 #endif
77 #ifdef ISAL_DEF_LVL7_DEFAULT
78         ISAL_DEF_LVL7_DEFAULT,
79 #else
80         0,
81 #endif
82 #ifdef ISAL_DEF_LVL8_DEFAULT
83         ISAL_DEF_LVL8_DEFAULT,
84 #else
85         0,
86 #endif
87 #ifdef ISAL_DEF_LVL9_DEFAULT
88         ISAL_DEF_LVL9_DEFAULT,
89 #else
90         0,
91 #endif
92 };
93 
94 int
usage(void)95 usage(void)
96 {
97         fprintf(stderr, "Usage: igzip_file_perf [options] <infile>\n"
98                         "  -h        help\n"
99                         "  -X        use compression level X with 0 <= X <= 1\n"
100                         "  -b <size> input buffer size, 0 buffers all the input\n"
101                         "  -i <time> time in seconds to benchmark (at least 0)\n"
102                         "  -o <file> output file for compressed data\n"
103                         "  -d <file> dictionary file used by compression\n"
104                         "  -w <size> log base 2 size of history window, between 8 and 15\n");
105 
106         exit(0);
107 }
108 
109 void
deflate_perf(struct isal_zstream * stream,uint8_t * inbuf,size_t infile_size,size_t inbuf_size,uint8_t * outbuf,size_t outbuf_size,int level,uint8_t * level_buf,int level_size,uint32_t hist_bits,uint8_t * dictbuf,size_t dictfile_size,struct isal_dict * dict_str,struct isal_hufftables * hufftables_custom)110 deflate_perf(struct isal_zstream *stream, uint8_t *inbuf, size_t infile_size, size_t inbuf_size,
111              uint8_t *outbuf, size_t outbuf_size, int level, uint8_t *level_buf, int level_size,
112              uint32_t hist_bits, uint8_t *dictbuf, size_t dictfile_size, struct isal_dict *dict_str,
113              struct isal_hufftables *hufftables_custom)
114 {
115         int avail_in;
116         isal_deflate_init(stream);
117         stream->level = level;
118         stream->level_buf = level_buf;
119         stream->level_buf_size = level_size;
120 
121         if (COMP_OK != isal_deflate_reset_dict(stream, dict_str))
122                 if (dictbuf != NULL)
123                         isal_deflate_set_dict(stream, dictbuf, dictfile_size);
124 
125         stream->end_of_stream = 0;
126         stream->flush = NO_FLUSH;
127         stream->next_out = outbuf;
128         stream->avail_out = outbuf_size;
129         stream->next_in = inbuf;
130         if (hufftables_custom != NULL)
131                 stream->hufftables = hufftables_custom;
132         stream->hist_bits = hist_bits;
133         avail_in = infile_size;
134 
135         while (avail_in > 0) {
136                 stream->avail_in = avail_in >= inbuf_size ? inbuf_size : avail_in;
137                 avail_in -= inbuf_size;
138 
139                 if (avail_in <= 0)
140                         stream->end_of_stream = 1;
141 
142                 isal_deflate(stream);
143 
144                 if (stream->avail_in != 0)
145                         break;
146         }
147 }
148 
149 int
main(int argc,char * argv[])150 main(int argc, char *argv[])
151 {
152         FILE *in = NULL, *out = NULL, *dict = NULL;
153         unsigned char *inbuf, *outbuf, *level_buf = NULL, *dictbuf = NULL;
154         int c, time = BENCHMARK_TIME, inbuf_size = 0;
155         size_t infile_size, outbuf_size, dictfile_size;
156         struct isal_huff_histogram histogram;
157         struct isal_hufftables hufftables_custom;
158         int level = 0, level_size = 0;
159         char *in_file_name = NULL, *out_file_name = NULL, *dict_file_name = NULL;
160         uint32_t hist_bits = 0;
161         struct isal_zstream stream;
162 
163         while ((c = getopt(argc, argv, "h0123456789i:b:o:d:w:")) != -1) {
164                 if (c >= '0' && c <= '9') {
165                         if (c > '0' + ISAL_DEF_MAX_LEVEL)
166                                 usage();
167                         else {
168                                 level = c - '0';
169                                 level_size = level_size_buf[level];
170                         }
171                         continue;
172                 }
173 
174                 switch (c) {
175                 case 'o':
176                         out_file_name = optarg;
177                         break;
178                 case 'd':
179                         dict_file_name = optarg;
180                         break;
181                 case 'i':
182                         time = atoi(optarg);
183                         if (time < 0)
184                                 usage();
185                         break;
186                 case 'b':
187                         inbuf_size = atoi(optarg);
188                         break;
189                 case 'w':
190                         hist_bits = atoi(optarg);
191                         if (hist_bits > 15 || hist_bits < 8)
192                                 usage();
193                         break;
194                 case 'h':
195                 default:
196                         usage();
197                         break;
198                 }
199         }
200 
201         if (optind < argc) {
202                 in_file_name = argv[optind];
203                 in = fopen(in_file_name, "rb");
204         } else
205                 usage();
206 
207         if (!in) {
208                 fprintf(stderr, "Can't open %s for reading\n", in_file_name);
209                 exit(0);
210         }
211         if (out_file_name != NULL) {
212                 out = fopen(out_file_name, "wb");
213                 if (!out) {
214                         fprintf(stderr, "Can't open %s for writing\n", out_file_name);
215                         exit(0);
216                 }
217                 printf("outfile=%s\n", out_file_name);
218         }
219 
220         if (dict_file_name != NULL) {
221                 dict = fopen(dict_file_name, "rb");
222                 if (!dict) {
223                         fprintf(stderr, "Can't open %s for reading\n", dict_file_name);
224                         exit(0);
225                 }
226                 printf("outfile=%s\n", dict_file_name);
227         }
228 
229         if (hist_bits == 0)
230                 printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024);
231 
232         else if (hist_bits < 10)
233                 printf("Window Size: %.2f K\n", 1.0 * (1 << hist_bits) / 1024);
234         else
235                 printf("Window Size: %d K\n", (1 << hist_bits) / 1024);
236 
237         printf("igzip_file_perf: \n");
238         fflush(0);
239 
240         /* Allocate space for entire input file and output
241          * (assuming some possible expansion on output size)
242          */
243         infile_size = get_filesize(in);
244 
245         outbuf_size = 2 * infile_size + BUF_SIZE;
246 
247         dictfile_size = (dict_file_name != NULL) ? get_filesize(dict) : 0;
248 
249         inbuf = malloc(infile_size);
250         if (inbuf == NULL) {
251                 fprintf(stderr, "Can't allocate input buffer memory\n");
252                 exit(0);
253         }
254         outbuf = malloc(outbuf_size);
255         if (outbuf == NULL) {
256                 fprintf(stderr, "Can't allocate output buffer memory\n");
257                 exit(0);
258         }
259 
260         if (dictfile_size != 0) {
261                 dictbuf = malloc(dictfile_size);
262                 if (dictbuf == NULL) {
263                         fprintf(stderr, "Can't allocate dictionary buffer memory\n");
264                         exit(0);
265                 }
266         }
267 
268         if (level_size != 0) {
269                 level_buf = malloc(level_size);
270                 if (level_buf == NULL) {
271                         fprintf(stderr, "Can't allocate level buffer memory\n");
272                         exit(0);
273                 }
274         }
275 
276         inbuf_size = inbuf_size ? inbuf_size : infile_size;
277 
278         printf("igzip_file_perf: %s\n", in_file_name);
279 
280         /* Read complete input file into buffer */
281         stream.avail_in = (uint32_t) fread(inbuf, 1, infile_size, in);
282         if (stream.avail_in != infile_size) {
283                 fprintf(stderr, "Couldn't fit all of input file into buffer\n");
284                 exit(0);
285         }
286 
287         /* Read complete dictionary into buffer */
288         if ((dictfile_size != 0) && (dictfile_size != fread(dictbuf, 1, dictfile_size, dict))) {
289                 fprintf(stderr, "Couldn't fit all of dictionary file into buffer\n");
290                 exit(0);
291         }
292 
293         struct isal_dict dict_str;
294         stream.level = level;
295         isal_deflate_process_dict(&stream, &dict_str, dictbuf, dictfile_size);
296 
297         struct perf start;
298         if (time > 0) {
299                 BENCHMARK(&start, time,
300                           deflate_perf(&stream, inbuf, infile_size, inbuf_size, outbuf, outbuf_size,
301                                        level, level_buf, level_size, hist_bits, dictbuf,
302                                        dictfile_size, &dict_str, NULL));
303         } else {
304                 deflate_perf(&stream, inbuf, infile_size, inbuf_size, outbuf, outbuf_size, level,
305                              level_buf, level_size, hist_bits, dictbuf, dictfile_size, &dict_str,
306                              NULL);
307         }
308         if (stream.avail_in != 0) {
309                 fprintf(stderr, "Could not compress all of inbuf\n");
310                 exit(0);
311         }
312 
313         printf("  file %s - in_size=%lu out_size=%d ratio=%3.1f%%", in_file_name, infile_size,
314                stream.total_out, 100.0 * stream.total_out / infile_size);
315 
316         if (level == 0) {
317                 memset(&histogram, 0, sizeof(histogram));
318 
319                 isal_update_histogram(inbuf, infile_size, &histogram);
320                 isal_create_hufftables(&hufftables_custom, &histogram);
321 
322                 deflate_perf(&stream, inbuf, infile_size, inbuf_size, outbuf, outbuf_size, level,
323                              level_buf, level_size, hist_bits, dictbuf, dictfile_size, &dict_str,
324                              &hufftables_custom);
325 
326                 printf(" ratio_custom=%3.1f%%", 100.0 * stream.total_out / infile_size);
327         }
328         printf("\n");
329 
330         if (stream.avail_in != 0) {
331                 fprintf(stderr, "Could not compress all of inbuf\n");
332                 exit(0);
333         }
334 
335         printf("igzip_file: ");
336         perf_print(start, (long long) infile_size);
337 
338         if (argc > 2 && out) {
339                 printf("writing %s\n", out_file_name);
340                 fwrite(outbuf, 1, stream.total_out, out);
341                 fclose(out);
342         }
343 
344         fclose(in);
345         printf("End of igzip_file_perf\n\n");
346         fflush(0);
347         return 0;
348 }
349