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