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 { 96 fprintf(stderr, 97 "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 1)\n" 102 " -o <file> output file for compresed 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, 110 size_t inbuf_size, uint8_t * outbuf, size_t outbuf_size, int level, 111 uint8_t * level_buf, int level_size, uint32_t hist_bits, uint8_t * dictbuf, 112 size_t dictfile_size, struct isal_hufftables *hufftables_custom) 113 { 114 int avail_in; 115 isal_deflate_init(stream); 116 if (dictbuf != NULL) 117 isal_deflate_set_dict(stream, dictbuf, dictfile_size); 118 stream->end_of_stream = 0; 119 stream->flush = NO_FLUSH; 120 stream->level = level; 121 stream->level_buf = level_buf; 122 stream->level_buf_size = level_size; 123 stream->next_out = outbuf; 124 stream->avail_out = outbuf_size; 125 stream->next_in = inbuf; 126 if (hufftables_custom != NULL) 127 stream->hufftables = hufftables_custom; 128 stream->hist_bits = hist_bits; 129 avail_in = infile_size; 130 131 while (avail_in > 0) { 132 stream->avail_in = avail_in >= inbuf_size ? inbuf_size : avail_in; 133 avail_in -= inbuf_size; 134 135 if (avail_in <= 0) 136 stream->end_of_stream = 1; 137 138 isal_deflate(stream); 139 140 if (stream->avail_in != 0) 141 break; 142 } 143 } 144 145 int main(int argc, char *argv[]) 146 { 147 FILE *in = NULL, *out = NULL, *dict = NULL; 148 unsigned char *inbuf, *outbuf, *level_buf = NULL, *dictbuf = NULL; 149 int c, time = BENCHMARK_TIME, inbuf_size = 0; 150 size_t infile_size, outbuf_size, dictfile_size; 151 struct isal_huff_histogram histogram; 152 struct isal_hufftables hufftables_custom; 153 int level = 0, level_size = 0; 154 char *in_file_name = NULL, *out_file_name = NULL, *dict_file_name = NULL; 155 uint32_t hist_bits = 0; 156 struct isal_zstream stream; 157 158 while ((c = getopt(argc, argv, "h0123456789i:b:o:d:w:")) != -1) { 159 if (c >= '0' && c <= '9') { 160 if (c > '0' + ISAL_DEF_MAX_LEVEL) 161 usage(); 162 else { 163 level = c - '0'; 164 level_size = level_size_buf[level]; 165 } 166 continue; 167 } 168 169 switch (c) { 170 case 'o': 171 out_file_name = optarg; 172 break; 173 case 'd': 174 dict_file_name = optarg; 175 break; 176 case 'i': 177 time = atoi(optarg); 178 if (time < 1) 179 usage(); 180 break; 181 case 'b': 182 inbuf_size = atoi(optarg); 183 break; 184 case 'w': 185 hist_bits = atoi(optarg); 186 if (hist_bits > 15 || hist_bits < 8) 187 usage(); 188 break; 189 case 'h': 190 default: 191 usage(); 192 break; 193 } 194 } 195 196 if (optind < argc) { 197 in_file_name = argv[optind]; 198 in = fopen(in_file_name, "rb"); 199 } else 200 usage(); 201 202 if (!in) { 203 fprintf(stderr, "Can't open %s for reading\n", in_file_name); 204 exit(0); 205 } 206 if (out_file_name != NULL) { 207 out = fopen(out_file_name, "wb"); 208 if (!out) { 209 fprintf(stderr, "Can't open %s for writing\n", out_file_name); 210 exit(0); 211 } 212 printf("outfile=%s\n", out_file_name); 213 } 214 215 if (dict_file_name != NULL) { 216 dict = fopen(dict_file_name, "rb"); 217 if (!dict) { 218 fprintf(stderr, "Can't open %s for reading\n", dict_file_name); 219 exit(0); 220 } 221 printf("outfile=%s\n", dict_file_name); 222 } 223 224 if (hist_bits == 0) 225 printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024); 226 227 else if (hist_bits < 10) 228 printf("Window Size: %.2f K\n", 1.0 * (1 << hist_bits) / 1024); 229 else 230 printf("Window Size: %d K\n", (1 << hist_bits) / 1024); 231 232 printf("igzip_file_perf: \n"); 233 fflush(0); 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 240 outbuf_size = 2 * infile_size + BUF_SIZE; 241 242 dictfile_size = (dict_file_name != NULL) ? get_filesize(dict) : 0; 243 244 inbuf = malloc(infile_size); 245 if (inbuf == NULL) { 246 fprintf(stderr, "Can't allocate input buffer memory\n"); 247 exit(0); 248 } 249 outbuf = malloc(outbuf_size); 250 if (outbuf == NULL) { 251 fprintf(stderr, "Can't allocate output buffer memory\n"); 252 exit(0); 253 } 254 255 if (dictfile_size != 0) { 256 dictbuf = malloc(dictfile_size); 257 if (dictbuf == NULL) { 258 fprintf(stderr, "Can't allocate dictionary buffer memory\n"); 259 exit(0); 260 } 261 } 262 263 if (level_size != 0) { 264 level_buf = malloc(level_size); 265 if (level_buf == NULL) { 266 fprintf(stderr, "Can't allocate level buffer memory\n"); 267 exit(0); 268 } 269 } 270 271 inbuf_size = inbuf_size ? inbuf_size : infile_size; 272 273 printf("igzip_file_perf: %s\n", in_file_name); 274 275 /* Read complete input file into buffer */ 276 stream.avail_in = (uint32_t) fread(inbuf, 1, infile_size, in); 277 if (stream.avail_in != infile_size) { 278 fprintf(stderr, "Couldn't fit all of input file into buffer\n"); 279 exit(0); 280 } 281 282 /* Read complete dictionary into buffer */ 283 if ((dictfile_size != 0) && (dictfile_size != fread(dictbuf, 1, dictfile_size, dict))) { 284 fprintf(stderr, "Couldn't fit all of dictionary file into buffer\n"); 285 exit(0); 286 } 287 288 struct perf start; 289 BENCHMARK(&start, time, 290 deflate_perf(&stream, inbuf, infile_size, inbuf_size, outbuf, outbuf_size, 291 level, level_buf, level_size, hist_bits, dictbuf, 292 dictfile_size, NULL)); 293 if (stream.avail_in != 0) { 294 fprintf(stderr, "Could not compress all of inbuf\n"); 295 exit(0); 296 } 297 298 printf(" file %s - in_size=%lu out_size=%d ratio=%3.1f%%", 299 in_file_name, infile_size, stream.total_out, 300 100.0 * stream.total_out / infile_size); 301 302 if (level == 0) { 303 memset(&histogram, 0, sizeof(histogram)); 304 305 isal_update_histogram(inbuf, infile_size, &histogram); 306 isal_create_hufftables(&hufftables_custom, &histogram); 307 308 deflate_perf(&stream, inbuf, infile_size, inbuf_size, outbuf, outbuf_size, 309 level, level_buf, level_size, hist_bits, dictbuf, 310 dictfile_size, &hufftables_custom); 311 312 printf(" ratio_custom=%3.1f%%", 100.0 * stream.total_out / infile_size); 313 } 314 printf("\n"); 315 316 if (stream.avail_in != 0) { 317 fprintf(stderr, "Could not compress all of inbuf\n"); 318 exit(0); 319 } 320 321 printf("igzip_file: "); 322 perf_print(start, (long long)infile_size); 323 324 if (argc > 2 && out) { 325 printf("writing %s\n", out_file_name); 326 fwrite(outbuf, 1, stream.total_out, out); 327 fclose(out); 328 } 329 330 fclose(in); 331 printf("End of igzip_file_perf\n\n"); 332 fflush(0); 333 return 0; 334 } 335