1 /**********************************************************************
2 Copyright(c) 2011-2016 Intel Corporation All rights reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
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
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.
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 **********************************************************************/
30 #define _FILE_OFFSET_BITS 64
35 #include "igzip_lib.h"
38 #define MIN_BUF_SIZE (4 * 1024)
39 #define MIN_TEST_LOOPS 10
41 # define RUN_MEM_SIZE 500000000
44 #define DEFAULT_SEG_SIZE (512 * 1024)
45 #define DEFAULT_SAMPLE_SIZE (32 * 1024)
50 "Usage: igzip_semi_dynamic [options] <infile>\n"
52 " -v (don't) validate output by inflate and compare\n"
53 " -i <iter> iterations\n"
54 " -t <type> 1:stateless 0:(default)stateful\n"
55 " -c <size> chunk size default=%d\n"
56 " -s <size> sample size default=%d\n"
57 " -o <file> output file\n", DEFAULT_SEG_SIZE
, DEFAULT_SAMPLE_SIZE
);
66 int len
= strnlen(s
, ARG_MAX
);
67 if (len
< 2 || len
== ARG_MAX
)
84 i
*= (1024 * 1024 * 1024);
87 i
*= (1000 * 1000 * 1000);
93 int main(int argc
, char *argv
[])
95 FILE *in
= stdin
, *out
= NULL
;
96 unsigned char *inbuf
, *outbuf
;
98 uint64_t infile_size
, outbuf_size
;
99 int segment_size
= DEFAULT_SEG_SIZE
;
100 int sample_size
= DEFAULT_SAMPLE_SIZE
;
101 int check_output
= 1;
102 int iterations
= 0, do_stateless
= 0, do_stateful
= 1;
104 char *out_file_name
= NULL
;
105 struct isal_zstream stream
;
106 struct isal_huff_histogram histogram
;
107 struct isal_hufftables hufftable
;
109 while ((c
= getopt(argc
, argv
, "vht:c:s:o:i:")) != -1) {
115 if (atoi(optarg
) == 1) {
121 segment_size
= str_to_i(optarg
);
124 sample_size
= str_to_i(optarg
);
127 out_file_name
= optarg
;
130 iterations
= str_to_i(optarg
);
141 if (!(in
= fopen(argv
[optind
], "rb"))) {
142 fprintf(stderr
, "Can't open %s for reading\n", argv
[optind
]);
148 // Optionally open output file
149 if (out_file_name
!= NULL
) {
150 if (!(out
= fopen(out_file_name
, "wb"))) {
151 fprintf(stderr
, "Can't open %s for writing\n", out_file_name
);
156 printf("Window Size: %d K\n", IGZIP_HIST_SIZE
/ 1024);
159 * Allocate space for entire input file and output
160 * (assuming some possible expansion on output size)
162 infile_size
= get_filesize(in
);
163 if (infile_size
== 0) {
164 printf("Input file has zero length\n");
168 if (iterations
== 0) {
169 iterations
= RUN_MEM_SIZE
/ infile_size
;
170 if (iterations
< MIN_TEST_LOOPS
)
171 iterations
= MIN_TEST_LOOPS
;
174 outbuf_size
= infile_size
* 1.30 > MIN_BUF_SIZE
? infile_size
* 1.30 : MIN_BUF_SIZE
;
176 if (NULL
== (inbuf
= malloc(infile_size
))) {
177 fprintf(stderr
, "Can't allocate input buffer memory\n");
180 if (NULL
== (outbuf
= malloc(outbuf_size
))) {
181 fprintf(stderr
, "Can't allocate output buffer memory\n");
185 int hist_size
= sample_size
> segment_size
? segment_size
: sample_size
;
187 printf("semi-dynamic sample=%d segment=%d %s\n", hist_size
, segment_size
,
188 do_stateful
? "stateful" : "stateless");
189 printf("igzip_file_perf: %s %d iterations\n", argv
[optind
], iterations
);
191 // Read complete input file into buffer
192 stream
.avail_in
= (uint32_t) fread(inbuf
, 1, infile_size
, in
);
193 if (stream
.avail_in
!= infile_size
) {
194 fprintf(stderr
, "Couldn't fit all of input file into buffer\n");
198 struct perf start
, stop
;
203 for (i
= 0; i
< iterations
; i
++) {
204 isal_deflate_init(&stream
);
205 stream
.end_of_stream
= 0;
206 stream
.flush
= SYNC_FLUSH
;
207 stream
.next_in
= inbuf
;
208 stream
.next_out
= outbuf
;
209 stream
.avail_out
= outbuf_size
;
210 int remaining
= infile_size
;
211 int chunk_size
= segment_size
;
213 while (remaining
> 0) {
214 // Generate custom hufftables on sample
215 memset(&histogram
, 0, sizeof(struct isal_huff_histogram
));
216 if (remaining
< segment_size
* 2) {
217 chunk_size
= remaining
;
218 stream
.end_of_stream
= 1;
221 (hist_size
> chunk_size
) ? chunk_size
: hist_size
;
222 isal_update_histogram(stream
.next_in
, hist_rem
, &histogram
);
224 if (hist_rem
== chunk_size
)
225 isal_create_hufftables_subset(&hufftable
, &histogram
);
227 isal_create_hufftables(&hufftable
, &histogram
);
229 // Compress with custom table
230 stream
.avail_in
= chunk_size
;
231 stream
.hufftables
= &hufftable
;
232 remaining
-= chunk_size
;
233 isal_deflate(&stream
);
234 if (stream
.internal_state
.state
!= ZSTATE_NEW_HDR
)
244 for (i
= 0; i
< iterations
; i
++) {
245 isal_deflate_stateless_init(&stream
);
246 stream
.end_of_stream
= 0;
247 stream
.flush
= FULL_FLUSH
;
248 stream
.next_in
= inbuf
;
249 stream
.next_out
= outbuf
;
250 int remaining
= infile_size
;
251 int chunk_size
= segment_size
;
253 while (remaining
> 0) {
254 // Generate custom hufftables on sample
255 memset(&histogram
, 0, sizeof(struct isal_huff_histogram
));
256 if (remaining
< segment_size
* 2) {
257 chunk_size
= remaining
;
258 stream
.end_of_stream
= 1;
261 (hist_size
> chunk_size
) ? chunk_size
: hist_size
;
262 isal_update_histogram(stream
.next_in
, hist_rem
, &histogram
);
264 if (hist_rem
== chunk_size
)
265 isal_create_hufftables_subset(&hufftable
, &histogram
);
267 isal_create_hufftables(&hufftable
, &histogram
);
269 // Compress with custom table
270 stream
.avail_in
= chunk_size
;
271 stream
.avail_out
= chunk_size
+ 8 * (1 + (chunk_size
>> 16));
272 stream
.hufftables
= &hufftable
;
273 remaining
-= chunk_size
;
274 isal_deflate_stateless(&stream
);
275 if (stream
.avail_in
!= 0)
282 if (stream
.avail_in
!= 0) {
283 printf("Could not compress all of inbuf\n");
287 printf(" file %s - in_size=%lu out_size=%d iter=%d ratio=%3.1f%%\n", argv
[optind
],
288 infile_size
, stream
.total_out
, i
, 100.0 * stream
.total_out
/ infile_size
);
290 printf("igzip_file: ");
291 perf_print(stop
, start
, (long long)infile_size
* i
);
294 printf("writing %s\n", out_file_name
);
295 fwrite(outbuf
, 1, stream
.total_out
, out
);
302 unsigned char *inflate_buf
;
303 struct inflate_state istate
;
305 if (NULL
== (inflate_buf
= malloc(infile_size
))) {
306 fprintf(stderr
, "Can't allocate reconstruct buffer memory\n");
309 isal_inflate_init(&istate
);
310 istate
.next_in
= outbuf
;
311 istate
.avail_in
= stream
.total_out
;
312 istate
.next_out
= inflate_buf
;
313 istate
.avail_out
= infile_size
;
314 int check
= isal_inflate(&istate
);
316 if (memcmp(inflate_buf
, inbuf
, infile_size
)) {
317 printf("inflate check Fail\n");
318 printf(" ret %d total_inflate=%d\n", check
, istate
.total_out
);
319 for (i
= 0; i
< infile_size
; i
++) {
320 if (inbuf
[i
] != inflate_buf
[i
]) {
321 printf(" first diff at offset=%d\n", i
);
327 printf("inflate check Pass\n");
331 printf("End of igzip_semi_dyn_file_perf\n\n");