blob: 8dab71265929a68d45d96c371bc3f38cdf2db73e [file] [log] [blame]
Yann Collet4856a002015-01-24 01:58:16 +01001/*
2 bench.c - Demo module to benchmark open-source compression algorithms
3 Copyright (C) Yann Collet 2012-2015
4
5 GPL v2 License
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 You can contact the author at :
22 - zstd source repository : https://github.com/Cyan4973/zstd
23 - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
24*/
25
Yann Colletf3eca252015-10-22 15:31:46 +010026/* **************************************
Yann Collet4856a002015-01-24 01:58:16 +010027* Compiler Options
Yann Colletf3eca252015-10-22 15:31:46 +010028****************************************/
Yann Collet4856a002015-01-24 01:58:16 +010029/* Disable some Visual warning messages */
30#define _CRT_SECURE_NO_WARNINGS /* fopen */
31
Yann Colletf3eca252015-10-22 15:31:46 +010032/* Unix Large Files support (>4GB) */
Yann Collet4856a002015-01-24 01:58:16 +010033#define _FILE_OFFSET_BITS 64
Yann Colletf3eca252015-10-22 15:31:46 +010034#if (defined(__sun__) && (!defined(__LP64__))) /* Sun Solaris 32-bits requires specific definitions */
Yann Collet4856a002015-01-24 01:58:16 +010035# define _LARGEFILE_SOURCE
Yann Colletf3eca252015-10-22 15:31:46 +010036#elif ! defined(__LP64__) /* No point defining Large file for 64 bit */
Yann Collet4856a002015-01-24 01:58:16 +010037# define _LARGEFILE64_SOURCE
38#endif
39
Yann Colletf3eca252015-10-22 15:31:46 +010040/* S_ISREG & gettimeofday() are not supported by MSVC */
Yann Collet4856a002015-01-24 01:58:16 +010041#if defined(_MSC_VER) || defined(_WIN32)
42# define BMK_LEGACY_TIMER 1
43#endif
44
45
Yann Colletf3eca252015-10-22 15:31:46 +010046/* *************************************
Yann Collet4856a002015-01-24 01:58:16 +010047* Includes
Yann Colletf3eca252015-10-22 15:31:46 +010048***************************************/
Yann Collet4856a002015-01-24 01:58:16 +010049#include <stdlib.h> /* malloc, free */
50#include <string.h> /* memset */
Yann Colleteeb8ba12015-10-22 16:55:40 +010051#include <stdio.h> /* fprintf, fopen, ftello64 */
52#include <sys/types.h> /* stat64 */
53#include <sys/stat.h> /* stat64 */
Yann Collet4856a002015-01-24 01:58:16 +010054
Yann Colleteeb8ba12015-10-22 16:55:40 +010055/* Use ftime() if gettimeofday() is not available */
Yann Collet4856a002015-01-24 01:58:16 +010056#if defined(BMK_LEGACY_TIMER)
Yann Colleteeb8ba12015-10-22 16:55:40 +010057# include <sys/timeb.h> /* timeb, ftime */
Yann Collet4856a002015-01-24 01:58:16 +010058#else
Yann Colleteeb8ba12015-10-22 16:55:40 +010059# include <sys/time.h> /* gettimeofday */
Yann Collet4856a002015-01-24 01:58:16 +010060#endif
61
Yann Colletf3eca252015-10-22 15:31:46 +010062#include "mem.h"
Yann Collet4856a002015-01-24 01:58:16 +010063#include "zstd.h"
Yann Colletf3eca252015-10-22 15:31:46 +010064#include "zstdhc.h"
Yann Collet4856a002015-01-24 01:58:16 +010065#include "xxhash.h"
66
67
Yann Colletf3eca252015-10-22 15:31:46 +010068/* *************************************
Yann Collet4856a002015-01-24 01:58:16 +010069* Compiler specifics
Yann Colletf3eca252015-10-22 15:31:46 +010070***************************************/
Yann Collet4856a002015-01-24 01:58:16 +010071#if !defined(S_ISREG)
72# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
73#endif
74
75
Yann Colletf3eca252015-10-22 15:31:46 +010076/* *************************************
Yann Collet4856a002015-01-24 01:58:16 +010077* Constants
Yann Colletf3eca252015-10-22 15:31:46 +010078***************************************/
Yann Collet4856a002015-01-24 01:58:16 +010079#define NBLOOPS 3
80#define TIMELOOP 2500
81
82#define KB *(1 <<10)
83#define MB *(1 <<20)
84#define GB *(1U<<30)
85
Yann Collet050efba2015-11-03 09:49:30 +010086static const size_t maxMemory = sizeof(size_t)==4 ? (2 GB - 64 MB) : 8ULL GB;
Yann Collet4856a002015-01-24 01:58:16 +010087#define DEFAULT_CHUNKSIZE (4 MB)
88
89static U32 g_compressibilityDefault = 50;
90static U32 prime1 = 2654435761U;
91static U32 prime2 = 2246822519U;
92
93
Yann Colletf3eca252015-10-22 15:31:46 +010094/* *************************************
Yann Collet4856a002015-01-24 01:58:16 +010095* Macros
Yann Colletf3eca252015-10-22 15:31:46 +010096***************************************/
Yann Collet4856a002015-01-24 01:58:16 +010097#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
98
99
Yann Colletf3eca252015-10-22 15:31:46 +0100100/* *************************************
Yann Collet4856a002015-01-24 01:58:16 +0100101* Benchmark Parameters
Yann Colletf3eca252015-10-22 15:31:46 +0100102***************************************/
Yann Collet4856a002015-01-24 01:58:16 +0100103static int nbIterations = NBLOOPS;
Yann Collet1c00dc32015-10-21 08:22:25 +0100104static size_t g_blockSize = 0;
Yann Collet4856a002015-01-24 01:58:16 +0100105
106void BMK_SetNbIterations(int nbLoops)
107{
108 nbIterations = nbLoops;
109 DISPLAY("- %i iterations -\n", nbIterations);
110}
111
Yann Collet1c00dc32015-10-21 08:22:25 +0100112void BMK_SetBlockSize(size_t blockSize)
113{
114 g_blockSize = blockSize;
115 DISPLAY("using blocks of size %u KB \n", (U32)(blockSize>>10));
116}
117
Yann Collet4856a002015-01-24 01:58:16 +0100118
Yann Colletf3eca252015-10-22 15:31:46 +0100119/* ********************************************************
Yann Collet4856a002015-01-24 01:58:16 +0100120* Private functions
Yann Colletf3eca252015-10-22 15:31:46 +0100121**********************************************************/
Yann Collet4856a002015-01-24 01:58:16 +0100122
123#if defined(BMK_LEGACY_TIMER)
124
125static int BMK_GetMilliStart(void)
126{
127 /* Based on Legacy ftime()
128 * Rolls over every ~ 12.1 days (0x100000/24/60/60)
129 * Use GetMilliSpan to correct for rollover */
130 struct timeb tb;
131 int nCount;
132 ftime( &tb );
133 nCount = (int) (tb.millitm + (tb.time & 0xfffff) * 1000);
134 return nCount;
135}
136
137#else
138
139static int BMK_GetMilliStart(void)
140{
141 /* Based on newer gettimeofday()
142 * Use GetMilliSpan to correct for rollover */
143 struct timeval tv;
144 int nCount;
145 gettimeofday(&tv, NULL);
146 nCount = (int) (tv.tv_usec/1000 + (tv.tv_sec & 0xfffff) * 1000);
147 return nCount;
148}
149
150#endif
151
152
153static int BMK_GetMilliSpan( int nTimeStart )
154{
155 int nSpan = BMK_GetMilliStart() - nTimeStart;
156 if ( nSpan < 0 )
157 nSpan += 0x100000 * 1000;
158 return nSpan;
159}
160
161
Yann Colletf3eca252015-10-22 15:31:46 +0100162/* ********************************************************
Yann Collet4856a002015-01-24 01:58:16 +0100163* Data generator
Yann Colletf3eca252015-10-22 15:31:46 +0100164**********************************************************/
Yann Collet4856a002015-01-24 01:58:16 +0100165/* will hopefully be converted into ROL instruction by compiler */
166static U32 BMK_rotl32(unsigned val32, unsigned nbBits) { return((val32 << nbBits) | (val32 >> (32 - nbBits))); }
167
168static U32 BMK_rand(U32* src)
169{
170 U32 rand32 = *src;
171 rand32 *= prime1;
172 rand32 += prime2;
173 rand32 = BMK_rotl32(rand32, 13);
174 *src = rand32;
175 return rand32 >> 9;
176}
177
Yann Collet4856a002015-01-24 01:58:16 +0100178#define BMK_RAND15BITS ( BMK_rand(&seed) & 0x7FFF)
179#define BMK_RANDLENGTH ((BMK_rand(&seed) & 3) ? (BMK_rand(&seed) % 15) : (BMK_rand(&seed) % 510) + 15)
180#define BMK_RANDCHAR (BYTE)((BMK_rand(&seed) & 63) + '0')
181static void BMK_datagen(void* buffer, size_t bufferSize, double proba, U32 seed)
182{
183 BYTE* BBuffer = (BYTE*)buffer;
184 unsigned pos = 0;
185 U32 P32 = (U32)(32768 * proba);
186
187 /* First Byte */
188 BBuffer[pos++] = BMK_RANDCHAR;
189
190 while (pos < bufferSize)
191 {
192 /* Select : Literal (noise) or copy (within 64K) */
193 if (BMK_RAND15BITS < P32)
194 {
195 /* Match */
196 size_t match, end;
197 unsigned length = BMK_RANDLENGTH + 4;
198 unsigned offset = BMK_RAND15BITS + 1;
199 if (offset > pos) offset = pos;
200 match = pos - offset;
201 end = pos + length;
202 if (end > bufferSize) end = bufferSize;
203 while (pos < end) BBuffer[pos++] = BBuffer[match++];
204 }
205 else
206 {
207 /* Literal */
208 size_t end;
209 unsigned length = BMK_RANDLENGTH;
210 end = pos + length;
211 if (end > bufferSize) end = bufferSize;
212 while (pos < end) BBuffer[pos++] = BMK_RANDCHAR;
213 }
214 }
215}
216
217
Yann Colletf3eca252015-10-22 15:31:46 +0100218/* ********************************************************
Yann Collet4856a002015-01-24 01:58:16 +0100219* Bench functions
Yann Colletf3eca252015-10-22 15:31:46 +0100220**********************************************************/
Yann Collet1c00dc32015-10-21 08:22:25 +0100221typedef struct
Yann Collet4856a002015-01-24 01:58:16 +0100222{
Yann Collet1c00dc32015-10-21 08:22:25 +0100223 char* srcPtr;
224 size_t srcSize;
225 char* cPtr;
226 size_t cRoom;
227 size_t cSize;
228 char* resPtr;
229 size_t resSize;
230} blockParam_t;
231
Yann Collet2acb5d32015-10-29 16:49:43 +0100232typedef size_t (*compressor_t) (void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel);
Yann Colletf3eca252015-10-22 15:31:46 +0100233
Yann Collet2acb5d32015-10-29 16:49:43 +0100234static size_t local_compress_fast (void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel)
Yann Colletf3eca252015-10-22 15:31:46 +0100235{
236 (void)compressionLevel;
237 return ZSTD_compress(dst, maxDstSize, src, srcSize);
238}
239
Yann Colletbe2010e2015-10-31 12:57:14 +0100240#define MIN(a,b) ((a)<(b) ? (a) : (b))
Yann Collet1c00dc32015-10-21 08:22:25 +0100241
242static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* fileName, int cLevel)
243{
244 const size_t blockSize = g_blockSize ? g_blockSize : srcSize;
245 const U32 nbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize);
246 blockParam_t* const blockTable = (blockParam_t*) malloc(nbBlocks * sizeof(blockParam_t));
247 const size_t maxCompressedSize = (size_t)nbBlocks * ZSTD_compressBound(blockSize);
248 void* const compressedBuffer = malloc(maxCompressedSize);
249 void* const resultBuffer = malloc(srcSize);
Yann Colletc776c462015-10-29 19:10:54 +0100250 const compressor_t compressor = (cLevel <= 1) ? local_compress_fast : ZSTD_HC_compress;
Yann Collet4856a002015-01-24 01:58:16 +0100251 U64 crcOrig;
252
Yann Colletc776c462015-10-29 19:10:54 +0100253 /* init */
254 if (strlen(fileName)>16)
255 fileName += strlen(fileName)-16;
256
Yann Collet4856a002015-01-24 01:58:16 +0100257 /* Memory allocation & restrictions */
Yann Collet1c00dc32015-10-21 08:22:25 +0100258 if (!compressedBuffer || !resultBuffer || !blockTable)
Yann Collet4856a002015-01-24 01:58:16 +0100259 {
260 DISPLAY("\nError: not enough memory!\n");
261 free(compressedBuffer);
262 free(resultBuffer);
Yann Collet1c00dc32015-10-21 08:22:25 +0100263 free(blockTable);
Yann Collet4856a002015-01-24 01:58:16 +0100264 return 12;
265 }
266
267 /* Calculating input Checksum */
268 crcOrig = XXH64(srcBuffer, srcSize, 0);
269
Yann Collet1c00dc32015-10-21 08:22:25 +0100270 /* Init blockTable data */
271 {
272 U32 i;
273 size_t remaining = srcSize;
274 char* srcPtr = (char*)srcBuffer;
275 char* cPtr = (char*)compressedBuffer;
276 char* resPtr = (char*)resultBuffer;
277 for (i=0; i<nbBlocks; i++)
278 {
279 size_t thisBlockSize = MIN(remaining, blockSize);
280 blockTable[i].srcPtr = srcPtr;
281 blockTable[i].cPtr = cPtr;
282 blockTable[i].resPtr = resPtr;
283 blockTable[i].srcSize = thisBlockSize;
284 blockTable[i].cRoom = ZSTD_compressBound(thisBlockSize);
285 srcPtr += thisBlockSize;
286 cPtr += blockTable[i].cRoom;
287 resPtr += thisBlockSize;
288 remaining -= thisBlockSize;
289 }
290 }
291
Yann Collet4856a002015-01-24 01:58:16 +0100292 /* warmimg up memory */
Yann Collet1c00dc32015-10-21 08:22:25 +0100293 BMK_datagen(compressedBuffer, maxCompressedSize, 0.10, 1);
Yann Collet4856a002015-01-24 01:58:16 +0100294
295 /* Bench */
296 {
297 int loopNb;
298 size_t cSize = 0;
299 double fastestC = 100000000., fastestD = 100000000.;
300 double ratio = 0.;
301 U64 crcCheck = 0;
302
303 DISPLAY("\r%79s\r", "");
304 for (loopNb = 1; loopNb <= nbIterations; loopNb++)
305 {
306 int nbLoops;
307 int milliTime;
Yann Collet1c00dc32015-10-21 08:22:25 +0100308 U32 blockNb;
Yann Collet4856a002015-01-24 01:58:16 +0100309
310 /* Compression */
Yann Collet44fe9912015-10-29 22:02:40 +0100311 DISPLAY("%2i-%-17.17s :%10u ->\r", loopNb, fileName, (U32)srcSize);
Yann Collet4856a002015-01-24 01:58:16 +0100312 memset(compressedBuffer, 0xE5, maxCompressedSize);
313
314 nbLoops = 0;
315 milliTime = BMK_GetMilliStart();
316 while (BMK_GetMilliStart() == milliTime);
317 milliTime = BMK_GetMilliStart();
318 while (BMK_GetMilliSpan(milliTime) < TIMELOOP)
319 {
Yann Collet1c00dc32015-10-21 08:22:25 +0100320 for (blockNb=0; blockNb<nbBlocks; blockNb++)
Yann Colletf3eca252015-10-22 15:31:46 +0100321 blockTable[blockNb].cSize = compressor(blockTable[blockNb].cPtr, blockTable[blockNb].cRoom, blockTable[blockNb].srcPtr,blockTable[blockNb].srcSize, cLevel);
Yann Collet4856a002015-01-24 01:58:16 +0100322 nbLoops++;
323 }
324 milliTime = BMK_GetMilliSpan(milliTime);
325
Yann Collet1c00dc32015-10-21 08:22:25 +0100326 cSize = 0;
327 for (blockNb=0; blockNb<nbBlocks; blockNb++)
328 cSize += blockTable[blockNb].cSize;
Yann Collet4856a002015-01-24 01:58:16 +0100329 if ((double)milliTime < fastestC*nbLoops) fastestC = (double)milliTime / nbLoops;
Yann Collet2acb5d32015-10-29 16:49:43 +0100330 ratio = (double)srcSize / (double)cSize;
Yann Collet44fe9912015-10-29 22:02:40 +0100331 DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s\r", loopNb, fileName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000.);
Yann Collet4856a002015-01-24 01:58:16 +0100332
Yann Collet2acb5d32015-10-29 16:49:43 +0100333#if 1
Yann Collet4856a002015-01-24 01:58:16 +0100334 /* Decompression */
335 memset(resultBuffer, 0xD6, srcSize);
336
337 nbLoops = 0;
338 milliTime = BMK_GetMilliStart();
339 while (BMK_GetMilliStart() == milliTime);
340 milliTime = BMK_GetMilliStart();
Yann Collete8c6bb12015-07-26 00:23:57 +0100341 for ( ; BMK_GetMilliSpan(milliTime) < TIMELOOP; nbLoops++)
Yann Collet4856a002015-01-24 01:58:16 +0100342 {
Yann Collet1c00dc32015-10-21 08:22:25 +0100343 for (blockNb=0; blockNb<nbBlocks; blockNb++)
344 blockTable[blockNb].resSize = ZSTD_decompress(blockTable[blockNb].resPtr, blockTable[blockNb].srcSize,
345 blockTable[blockNb].cPtr, blockTable[blockNb].cSize);
Yann Collet4856a002015-01-24 01:58:16 +0100346 }
347 milliTime = BMK_GetMilliSpan(milliTime);
348
349 if ((double)milliTime < fastestD*nbLoops) fastestD = (double)milliTime / nbLoops;
Yann Collet44fe9912015-10-29 22:02:40 +0100350 DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s\r", loopNb, fileName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000., (double)srcSize / fastestD / 1000.);
Yann Collet4856a002015-01-24 01:58:16 +0100351
352 /* CRC Checking */
353 crcCheck = XXH64(resultBuffer, srcSize, 0);
354 if (crcOrig!=crcCheck)
355 {
Yann Colletf3eca252015-10-22 15:31:46 +0100356 unsigned u;
Yann Colleteeb8ba12015-10-22 16:55:40 +0100357 unsigned eBlockSize = (unsigned)(MIN(65536*2, blockSize));
Yann Collet4856a002015-01-24 01:58:16 +0100358 DISPLAY("\n!!! WARNING !!! %14s : Invalid Checksum : %x != %x\n", fileName, (unsigned)crcOrig, (unsigned)crcCheck);
Yann Colletf3eca252015-10-22 15:31:46 +0100359 for (u=0; u<srcSize; u++)
Yann Collet4856a002015-01-24 01:58:16 +0100360 {
Yann Colletf3eca252015-10-22 15:31:46 +0100361 if (((BYTE*)srcBuffer)[u] != ((BYTE*)resultBuffer)[u])
Yann Collet4856a002015-01-24 01:58:16 +0100362 {
Yann Colletf3eca252015-10-22 15:31:46 +0100363 printf("Decoding error at pos %u (block %u, pos %u) \n", u, u / eBlockSize, u % eBlockSize);
Yann Collet4856a002015-01-24 01:58:16 +0100364 break;
365 }
Yann Collet4856a002015-01-24 01:58:16 +0100366 }
367 break;
368 }
Yann Collete8c6bb12015-07-26 00:23:57 +0100369#endif
Yann Collet4856a002015-01-24 01:58:16 +0100370 }
371
372 if (crcOrig == crcCheck)
Yann Collet44fe9912015-10-29 22:02:40 +0100373 DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s \n", cLevel, fileName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000., (double)srcSize / fastestD / 1000.);
Yann Collet4856a002015-01-24 01:58:16 +0100374 }
375
376 /* End cleaning */
377 free(compressedBuffer);
378 free(resultBuffer);
379 return 0;
380}
381
382
383static U64 BMK_GetFileSize(char* infilename)
384{
385 int r;
386#if defined(_MSC_VER)
387 struct _stat64 statbuf;
388 r = _stat64(infilename, &statbuf);
389#else
390 struct stat statbuf;
391 r = stat(infilename, &statbuf);
392#endif
393 if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */
394 return (U64)statbuf.st_size;
395}
396
397static size_t BMK_findMaxMem(U64 requiredMem)
398{
399 size_t step = 64 MB;
400 BYTE* testmem = NULL;
401
402 requiredMem = (((requiredMem >> 26) + 1) << 26);
403 requiredMem += 2 * step;
Yann Collet050efba2015-11-03 09:49:30 +0100404 if (requiredMem > maxMemory) requiredMem = maxMemory;
Yann Collet4856a002015-01-24 01:58:16 +0100405
406 while (!testmem)
407 {
408 requiredMem -= step;
409 testmem = (BYTE*)malloc((size_t)requiredMem);
410 }
411
412 free(testmem);
413 return (size_t)(requiredMem - step);
414}
415
416static int BMK_benchOneFile(char* inFileName, int cLevel)
417{
418 FILE* inFile;
419 U64 inFileSize;
420 size_t benchedSize, readSize;
421 void* srcBuffer;
Yann Collet4114f952015-10-30 06:40:22 +0100422 int result=0;
Yann Collet4856a002015-01-24 01:58:16 +0100423
Yann Collet1c00dc32015-10-21 08:22:25 +0100424 /* Check file existence */
Yann Collet4856a002015-01-24 01:58:16 +0100425 inFile = fopen(inFileName, "rb");
426 if (inFile == NULL)
427 {
428 DISPLAY("Pb opening %s\n", inFileName);
429 return 11;
430 }
431
Yann Collet1c00dc32015-10-21 08:22:25 +0100432 /* Memory allocation & restrictions */
Yann Collet4856a002015-01-24 01:58:16 +0100433 inFileSize = BMK_GetFileSize(inFileName);
434 benchedSize = BMK_findMaxMem(inFileSize * 3) / 3;
435 if ((U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize;
436 if (benchedSize < inFileSize)
437 DISPLAY("Not enough memory for '%s' full size; testing %i MB only...\n", inFileName, (int)(benchedSize >> 20));
Yann Collet4856a002015-01-24 01:58:16 +0100438 srcBuffer = malloc(benchedSize);
Yann Collet4856a002015-01-24 01:58:16 +0100439 if (!srcBuffer)
440 {
441 DISPLAY("\nError: not enough memory!\n");
Yann Collet4856a002015-01-24 01:58:16 +0100442 fclose(inFile);
443 return 12;
444 }
445
Yann Collet1c00dc32015-10-21 08:22:25 +0100446 /* Fill input buffer */
Yann Collet4856a002015-01-24 01:58:16 +0100447 DISPLAY("Loading %s... \r", inFileName);
448 readSize = fread(srcBuffer, 1, benchedSize, inFile);
449 fclose(inFile);
450
451 if (readSize != benchedSize)
452 {
453 DISPLAY("\nError: problem reading file '%s' !! \n", inFileName);
454 free(srcBuffer);
455 return 13;
456 }
457
Yann Colleteeb8ba12015-10-22 16:55:40 +0100458 /* Bench */
Yann Colletc776c462015-10-29 19:10:54 +0100459 if (cLevel<0)
460 {
461 int l;
462 for (l=1; l <= -cLevel; l++)
463 result = BMK_benchMem(srcBuffer, benchedSize, inFileName, l);
464 }
465 else
466 result = BMK_benchMem(srcBuffer, benchedSize, inFileName, cLevel);
Yann Collet4856a002015-01-24 01:58:16 +0100467
Yann Colleteeb8ba12015-10-22 16:55:40 +0100468 /* clean up */
Yann Collet4856a002015-01-24 01:58:16 +0100469 free(srcBuffer);
470 DISPLAY("\n");
471 return result;
472}
473
474
475static int BMK_syntheticTest(int cLevel, double compressibility)
476{
477 size_t benchedSize = 10000000;
478 void* srcBuffer = malloc(benchedSize);
Yann Collet4114f952015-10-30 06:40:22 +0100479 int result=0;
Yann Collet4856a002015-01-24 01:58:16 +0100480 char name[20] = {0};
481
Yann Collet4856a002015-01-24 01:58:16 +0100482 /* Memory allocation */
483 if (!srcBuffer)
484 {
485 DISPLAY("\nError: not enough memory!\n");
486 free(srcBuffer);
487 return 12;
488 }
489
490 /* Fill input buffer */
491 BMK_datagen(srcBuffer, benchedSize, compressibility, 0);
492
493 /* Bench */
494#ifdef _MSC_VER
495 sprintf_s(name, 20, "Synthetic %2u%%", (unsigned)(compressibility*100));
496#else
497 snprintf (name, 20, "Synthetic %2u%%", (unsigned)(compressibility*100));
498#endif
Yann Colletc776c462015-10-29 19:10:54 +0100499 /* Bench */
500 if (cLevel<0)
501 {
502 int l;
503 for (l=1; l <= -cLevel; l++)
504 result = BMK_benchMem(srcBuffer, benchedSize, name, l);
505 }
506 else
507 result = BMK_benchMem(srcBuffer, benchedSize, name, cLevel);
Yann Collet4856a002015-01-24 01:58:16 +0100508
509 /* End */
510 free(srcBuffer);
511 DISPLAY("\n");
512 return result;
513}
514
515
Yann Collet213089c2015-06-18 07:43:16 -0800516int BMK_benchFiles(char** fileNamesTable, unsigned nbFiles, unsigned cLevel)
Yann Collet4856a002015-01-24 01:58:16 +0100517{
518 double compressibility = (double)g_compressibilityDefault / 100;
519
520 if (nbFiles == 0)
521 {
522 BMK_syntheticTest(cLevel, compressibility);
523 }
524 else
525 {
526 /* Loop for each file */
527 unsigned fileIdx = 0;
528 while (fileIdx<nbFiles)
529 {
530 BMK_benchOneFile(fileNamesTable[fileIdx], cLevel);
531 fileIdx++;
532 }
533 }
534 return 0;
535}
536