xref: /isa-l/igzip/igzip_file_perf.c (revision 48d74d6e51b8817de7d6f1fb2c9da2cef25cb9a3)
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 #define MIN_TEST_LOOPS   10
41 #ifndef RUN_MEM_SIZE
42 # define RUN_MEM_SIZE 500000000
43 #endif
44 
45 struct isal_zstream stream;
46 
47 int usage(void)
48 {
49 	fprintf(stderr,
50 		"Usage: igzip_file_perf [options] <infile>\n"
51 		"  -h        help\n"
52 		"  -X        use compression level X with 0 <= X <= 1\n"
53 		"  -b <size> input buffer size, 0 buffers all the input\n"
54 		"  -i <iter> number of iterations (at least 1)\n"
55 		"  -o <file> output file for compresed data\n"
56 		"  -d <file> dictionary file used by compression\n");
57 
58 	exit(0);
59 }
60 
61 int main(int argc, char *argv[])
62 {
63 	FILE *in = NULL, *out = NULL, *dict = NULL;
64 	unsigned char *inbuf, *outbuf, *level_buf = NULL, *dictbuf = NULL;
65 	int i, c, iterations = 0, inbuf_size = 0;
66 	uint64_t infile_size, outbuf_size, dictfile_size;
67 	struct isal_huff_histogram histogram;
68 	struct isal_hufftables hufftables_custom;
69 	int level = 0, level_size = 0, avail_in;
70 	char *in_file_name = NULL, *out_file_name = NULL, *dict_file_name = NULL;
71 
72 	while ((c = getopt(argc, argv, "h01i:b:o:d:")) != -1) {
73 		switch (c) {
74 		case 'o':
75 			out_file_name = optarg;
76 			break;
77 		case 'd':
78 			dict_file_name = optarg;
79 			break;
80 		case 'i':
81 			iterations = atoi(optarg);
82 			if (iterations < 1)
83 				usage();
84 			break;
85 		case 'b':
86 			inbuf_size = atoi(optarg);
87 			break;
88 		case '1':
89 			level = 1;
90 			level_size = ISAL_DEF_LVL1_LARGE;
91 			break;
92 		case '0':
93 			break;
94 		case 'h':
95 		default:
96 			usage();
97 			break;
98 		}
99 	}
100 
101 	if (optind < argc) {
102 		in_file_name = argv[optind];
103 		in = fopen(in_file_name, "rb");
104 	} else
105 		usage();
106 
107 	if (!in) {
108 		fprintf(stderr, "Can't open %s for reading\n", in_file_name);
109 		exit(0);
110 	}
111 	if (out_file_name != NULL) {
112 		out = fopen(out_file_name, "wb");
113 		if (!out) {
114 			fprintf(stderr, "Can't open %s for writing\n", out_file_name);
115 			exit(0);
116 		}
117 		printf("outfile=%s\n", out_file_name);
118 	}
119 
120 	if (dict_file_name != NULL) {
121 		dict = fopen(dict_file_name, "rb");
122 		if (!dict) {
123 			fprintf(stderr, "Can't open %s for reading\n", dict_file_name);
124 			exit(0);
125 		}
126 		printf("outfile=%s\n", dict_file_name);
127 	}
128 
129 	printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024);
130 	printf("igzip_file_perf: \n");
131 	fflush(0);
132 
133 	/* Allocate space for entire input file and output
134 	 * (assuming some possible expansion on output size)
135 	 */
136 	infile_size = get_filesize(in);
137 
138 	outbuf_size = 2 * infile_size + BUF_SIZE;
139 
140 	dictfile_size = (dict_file_name != NULL) ? get_filesize(dict) : 0;
141 
142 	if (iterations == 0) {
143 		iterations = infile_size ? RUN_MEM_SIZE / infile_size : MIN_TEST_LOOPS;
144 		if (iterations < MIN_TEST_LOOPS)
145 			iterations = MIN_TEST_LOOPS;
146 	}
147 
148 	inbuf = malloc(infile_size);
149 	if (inbuf == NULL) {
150 		fprintf(stderr, "Can't allocate input buffer memory\n");
151 		exit(0);
152 	}
153 	outbuf = malloc(outbuf_size);
154 	if (outbuf == NULL) {
155 		fprintf(stderr, "Can't allocate output buffer memory\n");
156 		exit(0);
157 	}
158 
159 	if (dictfile_size != 0) {
160 		dictbuf = malloc(dictfile_size);
161 		if (dictbuf == NULL) {
162 			fprintf(stderr, "Can't allocate dictionary buffer memory\n");
163 			exit(0);
164 		}
165 	}
166 
167 	if (level_size != 0) {
168 		level_buf = malloc(level_size);
169 		if (level_buf == NULL) {
170 			fprintf(stderr, "Can't allocate level buffer memory\n");
171 			exit(0);
172 		}
173 	}
174 
175 	inbuf_size = inbuf_size ? inbuf_size : infile_size;
176 
177 	printf("igzip_file_perf: %s %d iterations\n", in_file_name, iterations);
178 
179 	/* Read complete input file into buffer */
180 	stream.avail_in = (uint32_t) fread(inbuf, 1, infile_size, in);
181 	if (stream.avail_in != infile_size) {
182 		fprintf(stderr, "Couldn't fit all of input file into buffer\n");
183 		exit(0);
184 	}
185 
186 	/* Read complete dictionary into buffer */
187 	if ((dictfile_size != 0) && (dictfile_size != fread(dictbuf, 1, dictfile_size, dict))) {
188 		fprintf(stderr, "Couldn't fit all of dictionary file into buffer\n");
189 		exit(0);
190 	}
191 
192 	struct perf start, stop;
193 	perf_start(&start);
194 
195 	for (i = 0; i < iterations; i++) {
196 		isal_deflate_init(&stream);
197 		if (dict_file_name != NULL)
198 			isal_deflate_set_dict(&stream, dictbuf, dictfile_size);
199 		stream.end_of_stream = 0;
200 		stream.flush = NO_FLUSH;
201 		stream.level = level;
202 		stream.level_buf = level_buf;
203 		stream.level_buf_size = level_size;
204 		stream.next_out = outbuf;
205 		stream.avail_out = outbuf_size;
206 		stream.next_in = inbuf;
207 		avail_in = infile_size;
208 
209 		while (avail_in > 0) {
210 			stream.avail_in = avail_in >= inbuf_size ? inbuf_size : avail_in;
211 			avail_in -= inbuf_size;
212 
213 			if (avail_in <= 0)
214 				stream.end_of_stream = 1;
215 
216 			isal_deflate(&stream);
217 
218 			if (stream.avail_in != 0)
219 				break;
220 		}
221 	}
222 
223 	perf_stop(&stop);
224 
225 	if (stream.avail_in != 0) {
226 		fprintf(stderr, "Could not compress all of inbuf\n");
227 		exit(0);
228 	}
229 
230 	printf("  file %s - in_size=%lu out_size=%d iter=%d ratio=%3.1f%%",
231 	       in_file_name, infile_size, stream.total_out, i,
232 	       100.0 * stream.total_out / infile_size);
233 
234 	if (level == 0) {
235 		memset(&histogram, 0, sizeof(histogram));
236 
237 		isal_update_histogram(inbuf, infile_size, &histogram);
238 		isal_create_hufftables(&hufftables_custom, &histogram);
239 
240 		isal_deflate_init(&stream);
241 		stream.end_of_stream = 0;
242 		stream.flush = NO_FLUSH;
243 		stream.level = level;
244 		stream.level_buf = level_buf;
245 		stream.level_buf_size = level_size;
246 		stream.next_out = outbuf;
247 		stream.avail_out = outbuf_size;
248 		stream.next_in = inbuf;
249 		stream.hufftables = &hufftables_custom;
250 		avail_in = infile_size;
251 
252 		while (avail_in > 0) {
253 			stream.avail_in = avail_in >= inbuf_size ? inbuf_size : avail_in;
254 			avail_in -= inbuf_size;
255 
256 			if (avail_in <= 0)
257 				stream.end_of_stream = 1;
258 
259 			isal_deflate(&stream);
260 
261 			if (stream.avail_in != 0)
262 				break;
263 		}
264 
265 		printf(" ratio_custom=%3.1f%%", 100.0 * stream.total_out / infile_size);
266 	}
267 	printf("\n");
268 
269 	if (stream.avail_in != 0) {
270 		fprintf(stderr, "Could not compress all of inbuf\n");
271 		exit(0);
272 	}
273 
274 	printf("igzip_file: ");
275 	perf_print(stop, start, (long long)infile_size * i);
276 
277 	if (argc > 2 && out) {
278 		printf("writing %s\n", out_file_name);
279 		fwrite(outbuf, 1, stream.total_out, out);
280 		fclose(out);
281 	}
282 
283 	fclose(in);
284 	printf("End of igzip_file_perf\n\n");
285 	fflush(0);
286 	return 0;
287 }
288