]> git.proxmox.com Git - ceph.git/blame - ceph/src/isa-l/igzip/igzip_semi_dyn_file_perf.c
Import ceph 15.2.8
[ceph.git] / ceph / src / isa-l / igzip / igzip_semi_dyn_file_perf.c
CommitLineData
224ce89b
WB
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
f91f0fd5 30#define _FILE_OFFSET_BITS 64
224ce89b
WB
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <getopt.h>
35#include "igzip_lib.h"
36#include "test.h"
37
38#define MIN_BUF_SIZE (4 * 1024)
39#define MIN_TEST_LOOPS 10
40#ifndef RUN_MEM_SIZE
41# define RUN_MEM_SIZE 500000000
42#endif
43
44#define DEFAULT_SEG_SIZE (512 * 1024)
45#define DEFAULT_SAMPLE_SIZE (32 * 1024)
46
47int usage(void)
48{
49 fprintf(stderr,
50 "Usage: igzip_semi_dynamic [options] <infile>\n"
51 " -h help\n"
52 " -v (don't) validate output by inflate and compare\n"
224ce89b
WB
53 " -t <type> 1:stateless 0:(default)stateful\n"
54 " -c <size> chunk size default=%d\n"
55 " -s <size> sample size default=%d\n"
56 " -o <file> output file\n", DEFAULT_SEG_SIZE, DEFAULT_SAMPLE_SIZE);
57 exit(0);
58}
59
60int str_to_i(char *s)
61{
62#define ARG_MAX 32
63
64 int i = atoi(s);
65 int len = strnlen(s, ARG_MAX);
66 if (len < 2 || len == ARG_MAX)
67 return i;
68
69 switch (s[len - 1]) {
70 case 'k':
71 i *= 1024;
72 break;
73 case 'K':
74 i *= 1000;
75 break;
76 case 'm':
77 i *= (1024 * 1024);
78 break;
79 case 'M':
80 i *= (1000 * 1000);
81 break;
82 case 'g':
83 i *= (1024 * 1024 * 1024);
84 break;
85 case 'G':
86 i *= (1000 * 1000 * 1000);
87 break;
88 }
89 return i;
90}
91
f91f0fd5
TL
92void semi_dyn_stateless_perf(struct isal_zstream *stream, uint8_t * inbuf,
93 uint64_t infile_size, uint8_t * outbuf, uint64_t outbuf_size,
94 int segment_size, int hist_size)
224ce89b 95{
f91f0fd5
TL
96 struct isal_huff_histogram histogram;
97 struct isal_hufftables hufftable;
98
99 isal_deflate_stateless_init(stream);
100 stream->end_of_stream = 0;
101 stream->flush = FULL_FLUSH;
102 stream->next_in = inbuf;
103 stream->next_out = outbuf;
104 int remaining = infile_size;
105 int chunk_size = segment_size;
106
107 while (remaining > 0) {
108 // Generate custom hufftables on sample
109 memset(&histogram, 0, sizeof(struct isal_huff_histogram));
110 if (remaining < segment_size * 2) {
111 chunk_size = remaining;
112 stream->end_of_stream = 1;
113 }
114 int hist_rem = (hist_size > chunk_size) ? chunk_size : hist_size;
115 isal_update_histogram(stream->next_in, hist_rem, &histogram);
116
117 if (hist_rem == chunk_size)
118 isal_create_hufftables_subset(&hufftable, &histogram);
119 else
120 isal_create_hufftables(&hufftable, &histogram);
121
122 // Compress with custom table
123 stream->avail_in = chunk_size;
124 stream->avail_out = chunk_size + 8 * (1 + (chunk_size >> 16));
125 stream->hufftables = &hufftable;
126 remaining -= chunk_size;
127 isal_deflate_stateless(stream);
128 if (stream->avail_in != 0)
129 break;
130 }
131}
224ce89b 132
f91f0fd5
TL
133void semi_dyn_stateful_perf(struct isal_zstream *stream, uint8_t * inbuf,
134 uint64_t infile_size, uint8_t * outbuf, uint64_t outbuf_size,
135 int segment_size, int hist_size)
136{
137 struct isal_huff_histogram histogram;
138 struct isal_hufftables hufftable;
139
140 isal_deflate_init(stream);
141 stream->end_of_stream = 0;
142 stream->flush = SYNC_FLUSH;
143 stream->next_in = inbuf;
144 stream->next_out = outbuf;
145 stream->avail_out = outbuf_size;
146 int remaining = infile_size;
147 int chunk_size = segment_size;
148
149 while (remaining > 0) {
150 // Generate custom hufftables on sample
151 memset(&histogram, 0, sizeof(struct isal_huff_histogram));
152 if (remaining < segment_size * 2) {
153 chunk_size = remaining;
154 stream->end_of_stream = 1;
155 }
156 int hist_rem = (hist_size > chunk_size) ? chunk_size : hist_size;
157 isal_update_histogram(stream->next_in, hist_rem, &histogram);
158
159 if (hist_rem == chunk_size)
160 isal_create_hufftables_subset(&hufftable, &histogram);
161 else
162 isal_create_hufftables(&hufftable, &histogram);
163
164 // Compress with custom table
165 stream->avail_in = chunk_size;
166 stream->hufftables = &hufftable;
167 remaining -= chunk_size;
168 isal_deflate(stream);
169 if (stream->internal_state.state != ZSTATE_NEW_HDR)
170 break;
171 }
224ce89b
WB
172}
173
174int main(int argc, char *argv[])
175{
176 FILE *in = stdin, *out = NULL;
177 unsigned char *inbuf, *outbuf;
f91f0fd5
TL
178 int i = 0, c;
179 uint64_t infile_size, outbuf_size;
224ce89b
WB
180 int segment_size = DEFAULT_SEG_SIZE;
181 int sample_size = DEFAULT_SAMPLE_SIZE;
182 int check_output = 1;
f91f0fd5 183 int do_stateless = 0, do_stateful = 1;
224ce89b
WB
184 int ret = 0;
185 char *out_file_name = NULL;
186 struct isal_zstream stream;
224ce89b 187
f91f0fd5 188 while ((c = getopt(argc, argv, "vht:c:s:o:")) != -1) {
224ce89b
WB
189 switch (c) {
190 case 'v':
191 check_output ^= 1;
192 break;
193 case 't':
194 if (atoi(optarg) == 1) {
195 do_stateful = 0;
196 do_stateless = 1;
197 }
198 break;
199 case 'c':
200 segment_size = str_to_i(optarg);
201 break;
202 case 's':
203 sample_size = str_to_i(optarg);
204 break;
205 case 'o':
206 out_file_name = optarg;
207 break;
224ce89b
WB
208 case 'h':
209 default:
210 usage();
211 break;
212 }
213 }
214
215 // Open input file
216 if (optind < argc) {
217 if (!(in = fopen(argv[optind], "rb"))) {
218 fprintf(stderr, "Can't open %s for reading\n", argv[optind]);
219 exit(1);
220 }
221 } else
222 usage();
223
224 // Optionally open output file
225 if (out_file_name != NULL) {
226 if (!(out = fopen(out_file_name, "wb"))) {
227 fprintf(stderr, "Can't open %s for writing\n", out_file_name);
228 exit(1);
229 }
230 }
231
232 printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024);
233
234 /*
235 * Allocate space for entire input file and output
236 * (assuming some possible expansion on output size)
237 */
238 infile_size = get_filesize(in);
239 if (infile_size == 0) {
240 printf("Input file has zero length\n");
241 usage();
242 }
243
224ce89b
WB
244 outbuf_size = infile_size * 1.30 > MIN_BUF_SIZE ? infile_size * 1.30 : MIN_BUF_SIZE;
245
246 if (NULL == (inbuf = malloc(infile_size))) {
247 fprintf(stderr, "Can't allocate input buffer memory\n");
248 exit(0);
249 }
250 if (NULL == (outbuf = malloc(outbuf_size))) {
251 fprintf(stderr, "Can't allocate output buffer memory\n");
252 exit(0);
253 }
254
255 int hist_size = sample_size > segment_size ? segment_size : sample_size;
256
257 printf("semi-dynamic sample=%d segment=%d %s\n", hist_size, segment_size,
258 do_stateful ? "stateful" : "stateless");
f91f0fd5 259 printf("igzip_file_perf: %s\n", argv[optind]);
224ce89b
WB
260
261 // Read complete input file into buffer
262 stream.avail_in = (uint32_t) fread(inbuf, 1, infile_size, in);
263 if (stream.avail_in != infile_size) {
264 fprintf(stderr, "Couldn't fit all of input file into buffer\n");
265 exit(0);
266 }
267
f91f0fd5 268 struct perf start;
224ce89b
WB
269
270 if (do_stateful) {
f91f0fd5
TL
271 BENCHMARK(&start, BENCHMARK_TIME,
272 semi_dyn_stateful_perf(&stream, inbuf, infile_size, outbuf,
273 outbuf_size, segment_size, hist_size)
274 );
224ce89b
WB
275 }
276
277 if (do_stateless) {
f91f0fd5
TL
278 BENCHMARK(&start, BENCHMARK_TIME,
279 semi_dyn_stateless_perf(&stream, inbuf, infile_size, outbuf,
280 outbuf_size, segment_size, hist_size));
224ce89b
WB
281 }
282
283 if (stream.avail_in != 0) {
284 printf("Could not compress all of inbuf\n");
285 ret = 1;
286 }
287
f91f0fd5 288 printf(" file %s - in_size=%lu out_size=%d iter=%d ratio=%3.1f%%\n", argv[optind],
224ce89b
WB
289 infile_size, stream.total_out, i, 100.0 * stream.total_out / infile_size);
290
f91f0fd5
TL
291 printf("igzip_semi_dyn_file: ");
292 perf_print(start, (long long)infile_size);
224ce89b
WB
293
294 if (out != NULL) {
295 printf("writing %s\n", out_file_name);
296 fwrite(outbuf, 1, stream.total_out, out);
297 fclose(out);
298 }
299
300 fclose(in);
301
302 if (check_output) {
303 unsigned char *inflate_buf;
304 struct inflate_state istate;
305
306 if (NULL == (inflate_buf = malloc(infile_size))) {
307 fprintf(stderr, "Can't allocate reconstruct buffer memory\n");
308 exit(0);
309 }
310 isal_inflate_init(&istate);
311 istate.next_in = outbuf;
312 istate.avail_in = stream.total_out;
313 istate.next_out = inflate_buf;
314 istate.avail_out = infile_size;
315 int check = isal_inflate(&istate);
316
317 if (memcmp(inflate_buf, inbuf, infile_size)) {
318 printf("inflate check Fail\n");
319 printf(" ret %d total_inflate=%d\n", check, istate.total_out);
320 for (i = 0; i < infile_size; i++) {
321 if (inbuf[i] != inflate_buf[i]) {
322 printf(" first diff at offset=%d\n", i);
323 break;
324 }
325 }
326 ret = 1;
327 } else
328 printf("inflate check Pass\n");
329 free(inflate_buf);
330 }
331
332 printf("End of igzip_semi_dyn_file_perf\n\n");
333 return ret;
334}