1
by mmach
test 1 |
1 |
/*
|
16
by mmach
1.5.4 |
2 |
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
1
by mmach
test 1 |
3 |
* All rights reserved.
|
4 |
*
|
|
5 |
* This source code is licensed under both the BSD-style license (found in the
|
|
6 |
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
7 |
* in the COPYING file in the root directory of this source tree).
|
|
8 |
* You may select, at your option, one of the above-listed licenses.
|
|
9 |
*/
|
|
10 |
||
11 |
||
12 |
/*_************************************
|
|
13 |
* Includes
|
|
14 |
**************************************/
|
|
8
by mmach
1.5.0 |
15 |
#define ZSTD_DISABLE_DEPRECATE_WARNINGS /* No deprecation warnings, we still bench some deprecated functions */ |
1
by mmach
test 1 |
16 |
#include "util.h" /* Compiler options, UTIL_GetFileSize */ |
17 |
#include <stdlib.h> /* malloc */ |
|
18 |
#include <stdio.h> /* fprintf, fopen, ftello64 */ |
|
19 |
#include <assert.h> |
|
20 |
||
21 |
#include "timefn.h" /* UTIL_clockSpanNano, UTIL_getTime */ |
|
22 |
#include "mem.h" /* U32 */ |
|
23 |
#ifndef ZSTD_DLL_IMPORT
|
|
24 |
#include "zstd_internal.h" /* ZSTD_decodeSeqHeaders, ZSTD_blockHeaderSize, ZSTD_getcBlockSize, blockType_e, KB, MB */ |
|
25 |
#include "decompress/zstd_decompress_internal.h" /* ZSTD_DCtx struct */ |
|
26 |
#else
|
|
27 |
#define KB *(1 <<10)
|
|
28 |
#define MB *(1 <<20)
|
|
29 |
#define GB *(1U<<30)
|
|
30 |
typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; |
|
31 |
#endif
|
|
32 |
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressBegin, ZSTD_compressContinue, etc. */ |
|
33 |
#include "zstd.h" /* ZSTD_versionString */ |
|
34 |
#include "util.h" /* time functions */ |
|
35 |
#include "datagen.h" |
|
36 |
#include "benchfn.h" /* CustomBench */ |
|
37 |
#include "benchzstd.h" /* MB_UNIT */ |
|
38 |
||
39 |
||
40 |
/*_************************************
|
|
41 |
* Constants
|
|
42 |
**************************************/
|
|
43 |
#define PROGRAM_DESCRIPTION "Zstandard speed analyzer"
|
|
44 |
#define AUTHOR "Yann Collet"
|
|
45 |
#define WELCOME_MESSAGE "*** %s %s %i-bits, by %s (%s) ***\n", PROGRAM_DESCRIPTION, ZSTD_versionString(), (int)(sizeof(void*)*8), AUTHOR, __DATE__
|
|
46 |
||
47 |
#define NBLOOPS 6
|
|
48 |
#define TIMELOOP_S 2
|
|
49 |
||
50 |
#define MAX_MEM (1984 MB)
|
|
51 |
||
52 |
#define DEFAULT_CLEVEL 1
|
|
53 |
||
54 |
#define COMPRESSIBILITY_DEFAULT 0.50
|
|
55 |
static const size_t kSampleSizeDefault = 10000000; |
|
56 |
||
57 |
#define TIMELOOP_NANOSEC (1*1000000000ULL) /* 1 second */ |
|
58 |
||
59 |
||
60 |
/*_************************************
|
|
61 |
* Macros
|
|
62 |
**************************************/
|
|
63 |
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
|
|
64 |
||
65 |
#define CONTROL(c) { if (!(c)) { abort(); } } /* like assert(), but cannot be disabled */ |
|
66 |
||
67 |
/*_************************************
|
|
68 |
* Benchmark Parameters
|
|
69 |
**************************************/
|
|
70 |
static unsigned g_nbIterations = NBLOOPS; |
|
71 |
||
72 |
||
73 |
/*_*******************************************************
|
|
74 |
* Private functions
|
|
75 |
*********************************************************/
|
|
76 |
static size_t BMK_findMaxMem(U64 requiredMem) |
|
77 |
{
|
|
78 |
size_t const step = 64 MB; |
|
79 |
void* testmem = NULL; |
|
80 |
||
81 |
requiredMem = (((requiredMem >> 26) + 1) << 26); |
|
82 |
if (requiredMem > MAX_MEM) requiredMem = MAX_MEM; |
|
83 |
||
84 |
requiredMem += step; |
|
85 |
do { |
|
86 |
testmem = malloc ((size_t)requiredMem); |
|
87 |
requiredMem -= step; |
|
88 |
} while (!testmem); |
|
89 |
||
90 |
free (testmem); |
|
91 |
return (size_t) requiredMem; |
|
92 |
}
|
|
93 |
||
94 |
||
95 |
/*_*******************************************************
|
|
96 |
* Benchmark wrappers
|
|
97 |
*********************************************************/
|
|
98 |
||
99 |
static ZSTD_CCtx* g_zcc = NULL; |
|
100 |
||
101 |
static size_t |
|
102 |
local_ZSTD_compress(const void* src, size_t srcSize, |
|
103 |
void* dst, size_t dstSize, |
|
104 |
void* payload) |
|
105 |
{
|
|
106 |
ZSTD_parameters p; |
|
107 |
ZSTD_frameParameters f = { 1 /* contentSizeHeader*/, 0, 0 }; |
|
108 |
p.fParams = f; |
|
109 |
p.cParams = *(ZSTD_compressionParameters*)payload; |
|
110 |
return ZSTD_compress_advanced (g_zcc, dst, dstSize, src, srcSize, NULL ,0, p); |
|
9
by mmach
152 |
111 |
}
|
112 |
||
113 |
static size_t |
|
114 |
local_ZSTD_compress_freshCCtx(const void* src, size_t srcSize, |
|
115 |
void* dst, size_t dstSize, |
|
116 |
void* payload) |
|
117 |
{
|
|
118 |
ZSTD_parameters p; |
|
119 |
ZSTD_frameParameters f = { 1 /* contentSizeHeader*/, 0, 0 }; |
|
120 |
p.fParams = f; |
|
121 |
p.cParams = *(ZSTD_compressionParameters*)payload; |
|
122 |
if (g_zcc != NULL) ZSTD_freeCCtx(g_zcc); |
|
123 |
g_zcc = ZSTD_createCCtx(); |
|
124 |
assert(g_zcc != NULL); |
|
125 |
{ size_t const r = ZSTD_compress_advanced (g_zcc, dst, dstSize, src, srcSize, NULL ,0, p); |
|
126 |
ZSTD_freeCCtx(g_zcc); |
|
127 |
g_zcc = NULL; |
|
128 |
return r; |
|
129 |
}
|
|
1
by mmach
test 1 |
130 |
}
|
131 |
||
132 |
static size_t g_cSize = 0; |
|
133 |
static size_t local_ZSTD_decompress(const void* src, size_t srcSize, |
|
134 |
void* dst, size_t dstSize, |
|
135 |
void* buff2) |
|
136 |
{
|
|
137 |
(void)src; (void)srcSize; |
|
138 |
return ZSTD_decompress(dst, dstSize, buff2, g_cSize); |
|
139 |
}
|
|
140 |
||
141 |
static ZSTD_DCtx* g_zdc = NULL; |
|
142 |
||
143 |
#ifndef ZSTD_DLL_IMPORT
|
|
9
by mmach
152 |
144 |
typedef enum { |
145 |
not_streaming = 0, |
|
146 |
is_streaming = 1 |
|
147 |
} streaming_operation; |
|
148 |
extern size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* ctx, const void* src, size_t srcSize, void* dst, size_t dstCapacity, const streaming_operation streaming); |
|
1
by mmach
test 1 |
149 |
static size_t local_ZSTD_decodeLiteralsBlock(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2) |
150 |
{
|
|
151 |
(void)src; (void)srcSize; (void)dst; (void)dstSize; |
|
9
by mmach
152 |
152 |
return ZSTD_decodeLiteralsBlock(g_zdc, buff2, g_cSize, dst, dstSize, not_streaming); |
1
by mmach
test 1 |
153 |
}
|
154 |
||
155 |
static size_t local_ZSTD_decodeSeqHeaders(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2) |
|
156 |
{
|
|
157 |
int nbSeq; |
|
158 |
(void)src; (void)srcSize; (void)dst; (void)dstSize; |
|
159 |
return ZSTD_decodeSeqHeaders(g_zdc, &nbSeq, buff2, g_cSize); |
|
160 |
}
|
|
161 |
||
162 |
FORCE_NOINLINE size_t ZSTD_decodeLiteralsHeader(ZSTD_DCtx* dctx, void const* src, size_t srcSize) |
|
163 |
{
|
|
164 |
RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, ""); |
|
165 |
{
|
|
166 |
BYTE const* istart = (BYTE const*)src; |
|
167 |
symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3); |
|
168 |
if (litEncType == set_compressed) { |
|
169 |
RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3"); |
|
170 |
{
|
|
171 |
size_t lhSize, litSize, litCSize; |
|
172 |
U32 const lhlCode = (istart[0] >> 2) & 3; |
|
173 |
U32 const lhc = MEM_readLE32(istart); |
|
16
by mmach
1.5.4 |
174 |
int const flags = ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0; |
1
by mmach
test 1 |
175 |
switch(lhlCode) |
176 |
{
|
|
177 |
case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */ |
|
178 |
/* 2 - 2 - 10 - 10 */
|
|
179 |
lhSize = 3; |
|
180 |
litSize = (lhc >> 4) & 0x3FF; |
|
181 |
litCSize = (lhc >> 14) & 0x3FF; |
|
182 |
break; |
|
183 |
case 2: |
|
184 |
/* 2 - 2 - 14 - 14 */
|
|
185 |
lhSize = 4; |
|
186 |
litSize = (lhc >> 4) & 0x3FFF; |
|
187 |
litCSize = lhc >> 18; |
|
188 |
break; |
|
189 |
case 3: |
|
190 |
/* 2 - 2 - 18 - 18 */
|
|
191 |
lhSize = 5; |
|
192 |
litSize = (lhc >> 4) & 0x3FFFF; |
|
193 |
litCSize = (lhc >> 22) + ((size_t)istart[4] << 10); |
|
194 |
break; |
|
195 |
}
|
|
196 |
RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, ""); |
|
197 |
RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, ""); |
|
198 |
#ifndef HUF_FORCE_DECOMPRESS_X2
|
|
16
by mmach
1.5.4 |
199 |
return HUF_readDTableX1_wksp( |
1
by mmach
test 1 |
200 |
dctx->entropy.hufTable, |
201 |
istart+lhSize, litCSize, |
|
202 |
dctx->workspace, sizeof(dctx->workspace), |
|
16
by mmach
1.5.4 |
203 |
flags); |
1
by mmach
test 1 |
204 |
#else
|
205 |
return HUF_readDTableX2_wksp( |
|
206 |
dctx->entropy.hufTable, |
|
207 |
istart+lhSize, litCSize, |
|
16
by mmach
1.5.4 |
208 |
dctx->workspace, sizeof(dctx->workspace), flags); |
1
by mmach
test 1 |
209 |
#endif
|
210 |
}
|
|
211 |
}
|
|
212 |
}
|
|
213 |
return 0; |
|
214 |
}
|
|
215 |
||
216 |
static size_t local_ZSTD_decodeLiteralsHeader(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2) |
|
217 |
{
|
|
218 |
(void)dst, (void)dstSize, (void)src, (void)srcSize; |
|
219 |
return ZSTD_decodeLiteralsHeader(g_zdc, buff2, g_cSize); |
|
220 |
}
|
|
221 |
#endif
|
|
222 |
||
223 |
static ZSTD_CStream* g_cstream= NULL; |
|
224 |
static size_t |
|
225 |
local_ZSTD_compressStream(const void* src, size_t srcSize, |
|
226 |
void* dst, size_t dstCapacity, |
|
227 |
void* payload) |
|
228 |
{
|
|
229 |
ZSTD_outBuffer buffOut; |
|
230 |
ZSTD_inBuffer buffIn; |
|
231 |
ZSTD_parameters p; |
|
232 |
ZSTD_frameParameters f = {1 /* contentSizeHeader*/, 0, 0}; |
|
233 |
p.fParams = f; |
|
234 |
p.cParams = *(ZSTD_compressionParameters*)payload; |
|
235 |
ZSTD_initCStream_advanced(g_cstream, NULL, 0, p, ZSTD_CONTENTSIZE_UNKNOWN); |
|
236 |
buffOut.dst = dst; |
|
237 |
buffOut.size = dstCapacity; |
|
238 |
buffOut.pos = 0; |
|
239 |
buffIn.src = src; |
|
240 |
buffIn.size = srcSize; |
|
241 |
buffIn.pos = 0; |
|
242 |
ZSTD_compressStream(g_cstream, &buffOut, &buffIn); |
|
243 |
ZSTD_endStream(g_cstream, &buffOut); |
|
244 |
return buffOut.pos; |
|
245 |
}
|
|
246 |
||
247 |
static size_t |
|
248 |
local_ZSTD_compressStream_freshCCtx(const void* src, size_t srcSize, |
|
249 |
void* dst, size_t dstCapacity, |
|
250 |
void* payload) |
|
251 |
{
|
|
9
by mmach
152 |
252 |
if (g_cstream != NULL) ZSTD_freeCCtx(g_cstream); |
253 |
g_cstream = ZSTD_createCCtx(); |
|
254 |
assert(g_cstream != NULL); |
|
255 |
||
256 |
{ size_t const r = local_ZSTD_compressStream(src, srcSize, dst, dstCapacity, payload); |
|
257 |
ZSTD_freeCCtx(g_cstream); |
|
258 |
g_cstream = NULL; |
|
259 |
return r; |
|
260 |
}
|
|
1
by mmach
test 1 |
261 |
}
|
262 |
||
263 |
static size_t |
|
264 |
local_ZSTD_compress2(const void* src, size_t srcSize, |
|
265 |
void* dst, size_t dstCapacity, |
|
266 |
void* payload) |
|
267 |
{
|
|
268 |
(void)payload; |
|
269 |
return ZSTD_compress2(g_cstream, dst, dstCapacity, src, srcSize); |
|
270 |
}
|
|
271 |
||
272 |
static size_t |
|
273 |
local_ZSTD_compressStream2_end(const void* src, size_t srcSize, |
|
274 |
void* dst, size_t dstCapacity, |
|
275 |
void* payload) |
|
276 |
{
|
|
277 |
ZSTD_outBuffer buffOut; |
|
278 |
ZSTD_inBuffer buffIn; |
|
279 |
(void)payload; |
|
280 |
buffOut.dst = dst; |
|
281 |
buffOut.size = dstCapacity; |
|
282 |
buffOut.pos = 0; |
|
283 |
buffIn.src = src; |
|
284 |
buffIn.size = srcSize; |
|
285 |
buffIn.pos = 0; |
|
286 |
ZSTD_compressStream2(g_cstream, &buffOut, &buffIn, ZSTD_e_end); |
|
287 |
return buffOut.pos; |
|
288 |
}
|
|
289 |
||
290 |
static size_t |
|
291 |
local_ZSTD_compressStream2_continue(const void* src, size_t srcSize, |
|
292 |
void* dst, size_t dstCapacity, |
|
293 |
void* payload) |
|
294 |
{
|
|
295 |
ZSTD_outBuffer buffOut; |
|
296 |
ZSTD_inBuffer buffIn; |
|
297 |
(void)payload; |
|
298 |
buffOut.dst = dst; |
|
299 |
buffOut.size = dstCapacity; |
|
300 |
buffOut.pos = 0; |
|
301 |
buffIn.src = src; |
|
302 |
buffIn.size = srcSize; |
|
303 |
buffIn.pos = 0; |
|
304 |
ZSTD_compressStream2(g_cstream, &buffOut, &buffIn, ZSTD_e_continue); |
|
305 |
ZSTD_compressStream2(g_cstream, &buffOut, &buffIn, ZSTD_e_end); |
|
306 |
return buffOut.pos; |
|
307 |
}
|
|
308 |
||
309 |
static size_t |
|
310 |
local_ZSTD_compress_generic_T2_end(const void* src, size_t srcSize, |
|
311 |
void* dst, size_t dstCapacity, |
|
312 |
void* payload) |
|
313 |
{
|
|
314 |
(void)payload; |
|
315 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_nbWorkers, 2); |
|
316 |
return ZSTD_compress2(g_cstream, dst, dstCapacity, src, srcSize); |
|
317 |
}
|
|
318 |
||
319 |
static size_t |
|
320 |
local_ZSTD_compress_generic_T2_continue(const void* src, size_t srcSize, |
|
321 |
void* dst, size_t dstCapacity, |
|
322 |
void* payload) |
|
323 |
{
|
|
324 |
ZSTD_outBuffer buffOut; |
|
325 |
ZSTD_inBuffer buffIn; |
|
326 |
(void)payload; |
|
327 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_nbWorkers, 2); |
|
328 |
buffOut.dst = dst; |
|
329 |
buffOut.size = dstCapacity; |
|
330 |
buffOut.pos = 0; |
|
331 |
buffIn.src = src; |
|
332 |
buffIn.size = srcSize; |
|
333 |
buffIn.pos = 0; |
|
334 |
ZSTD_compressStream2(g_cstream, &buffOut, &buffIn, ZSTD_e_continue); |
|
335 |
while(ZSTD_compressStream2(g_cstream, &buffOut, &buffIn, ZSTD_e_end)) {} |
|
336 |
return buffOut.pos; |
|
337 |
}
|
|
338 |
||
339 |
static ZSTD_DStream* g_dstream= NULL; |
|
340 |
static size_t |
|
341 |
local_ZSTD_decompressStream(const void* src, size_t srcSize, |
|
342 |
void* dst, size_t dstCapacity, |
|
343 |
void* buff2) |
|
344 |
{
|
|
345 |
ZSTD_outBuffer buffOut; |
|
346 |
ZSTD_inBuffer buffIn; |
|
347 |
(void)src; (void)srcSize; |
|
348 |
ZSTD_initDStream(g_dstream); |
|
349 |
buffOut.dst = dst; |
|
350 |
buffOut.size = dstCapacity; |
|
351 |
buffOut.pos = 0; |
|
352 |
buffIn.src = buff2; |
|
353 |
buffIn.size = g_cSize; |
|
354 |
buffIn.pos = 0; |
|
355 |
ZSTD_decompressStream(g_dstream, &buffOut, &buffIn); |
|
356 |
return buffOut.pos; |
|
357 |
}
|
|
358 |
||
359 |
#ifndef ZSTD_DLL_IMPORT
|
|
360 |
static size_t local_ZSTD_compressContinue(const void* src, size_t srcSize, |
|
361 |
void* dst, size_t dstCapacity, |
|
362 |
void* payload) |
|
363 |
{
|
|
364 |
ZSTD_parameters p; |
|
365 |
ZSTD_frameParameters f = { 1 /* contentSizeHeader*/, 0, 0 }; |
|
366 |
p.fParams = f; |
|
367 |
p.cParams = *(ZSTD_compressionParameters*)payload; |
|
368 |
ZSTD_compressBegin_advanced(g_zcc, NULL, 0, p, srcSize); |
|
369 |
return ZSTD_compressEnd(g_zcc, dst, dstCapacity, src, srcSize); |
|
370 |
}
|
|
371 |
||
372 |
#define FIRST_BLOCK_SIZE 8
|
|
373 |
static size_t |
|
374 |
local_ZSTD_compressContinue_extDict(const void* src, size_t srcSize, |
|
375 |
void* dst, size_t dstCapacity, |
|
376 |
void* payload) |
|
377 |
{
|
|
378 |
BYTE firstBlockBuf[FIRST_BLOCK_SIZE]; |
|
379 |
||
380 |
ZSTD_parameters p; |
|
381 |
ZSTD_frameParameters const f = { 1, 0, 0 }; |
|
382 |
p.fParams = f; |
|
383 |
p.cParams = *(ZSTD_compressionParameters*)payload; |
|
384 |
ZSTD_compressBegin_advanced(g_zcc, NULL, 0, p, srcSize); |
|
385 |
memcpy(firstBlockBuf, src, FIRST_BLOCK_SIZE); |
|
386 |
||
387 |
{ size_t const compressResult = ZSTD_compressContinue(g_zcc, |
|
388 |
dst, dstCapacity, |
|
389 |
firstBlockBuf, FIRST_BLOCK_SIZE); |
|
390 |
if (ZSTD_isError(compressResult)) { |
|
391 |
DISPLAY("local_ZSTD_compressContinue_extDict error : %s\n", |
|
392 |
ZSTD_getErrorName(compressResult)); |
|
393 |
return compressResult; |
|
394 |
}
|
|
395 |
dst = (BYTE*)dst + compressResult; |
|
396 |
dstCapacity -= compressResult; |
|
397 |
}
|
|
398 |
return ZSTD_compressEnd(g_zcc, dst, dstCapacity, |
|
399 |
(const BYTE*)src + FIRST_BLOCK_SIZE, |
|
400 |
srcSize - FIRST_BLOCK_SIZE); |
|
401 |
}
|
|
402 |
||
403 |
static size_t local_ZSTD_decompressContinue(const void* src, size_t srcSize, |
|
404 |
void* dst, size_t dstCapacity, |
|
405 |
void* buff2) |
|
406 |
{
|
|
407 |
size_t regeneratedSize = 0; |
|
408 |
const BYTE* ip = (const BYTE*)buff2; |
|
409 |
const BYTE* const iend = ip + g_cSize; |
|
410 |
BYTE* op = (BYTE*)dst; |
|
411 |
size_t remainingCapacity = dstCapacity; |
|
412 |
||
413 |
(void)src; (void)srcSize; /* unused */ |
|
414 |
ZSTD_decompressBegin(g_zdc); |
|
415 |
while (ip < iend) { |
|
416 |
size_t const iSize = ZSTD_nextSrcSizeToDecompress(g_zdc); |
|
417 |
size_t const decodedSize = ZSTD_decompressContinue(g_zdc, op, remainingCapacity, ip, iSize); |
|
418 |
ip += iSize; |
|
419 |
regeneratedSize += decodedSize; |
|
420 |
op += decodedSize; |
|
421 |
remainingCapacity -= decodedSize; |
|
422 |
}
|
|
423 |
||
424 |
return regeneratedSize; |
|
425 |
}
|
|
426 |
#endif
|
|
427 |
||
428 |
||
429 |
/*_*******************************************************
|
|
430 |
* Bench functions
|
|
431 |
*********************************************************/
|
|
432 |
static int benchMem(unsigned benchNb, |
|
433 |
const void* src, size_t srcSize, |
|
434 |
int cLevel, ZSTD_compressionParameters cparams) |
|
435 |
{
|
|
436 |
size_t dstBuffSize = ZSTD_compressBound(srcSize); |
|
437 |
BYTE* dstBuff; |
|
438 |
void* dstBuff2; |
|
439 |
void* payload; |
|
440 |
const char* benchName; |
|
441 |
BMK_benchFn_t benchFunction; |
|
442 |
int errorcode = 0; |
|
443 |
||
444 |
/* Selection */
|
|
445 |
switch(benchNb) |
|
446 |
{
|
|
447 |
case 1: |
|
448 |
benchFunction = local_ZSTD_compress; benchName = "compress"; |
|
449 |
break; |
|
450 |
case 2: |
|
451 |
benchFunction = local_ZSTD_decompress; benchName = "decompress"; |
|
452 |
break; |
|
9
by mmach
152 |
453 |
case 3: |
454 |
benchFunction = local_ZSTD_compress_freshCCtx; benchName = "compress_freshCCtx"; |
|
455 |
break; |
|
1
by mmach
test 1 |
456 |
#ifndef ZSTD_DLL_IMPORT
|
457 |
case 11: |
|
458 |
benchFunction = local_ZSTD_compressContinue; benchName = "compressContinue"; |
|
459 |
break; |
|
460 |
case 12: |
|
461 |
benchFunction = local_ZSTD_compressContinue_extDict; benchName = "compressContinue_extDict"; |
|
462 |
break; |
|
463 |
case 13: |
|
464 |
benchFunction = local_ZSTD_decompressContinue; benchName = "decompressContinue"; |
|
465 |
break; |
|
466 |
case 30: |
|
467 |
benchFunction = local_ZSTD_decodeLiteralsHeader; benchName = "decodeLiteralsHeader"; |
|
468 |
break; |
|
469 |
case 31: |
|
470 |
benchFunction = local_ZSTD_decodeLiteralsBlock; benchName = "decodeLiteralsBlock"; |
|
471 |
break; |
|
472 |
case 32: |
|
473 |
benchFunction = local_ZSTD_decodeSeqHeaders; benchName = "decodeSeqHeaders"; |
|
474 |
break; |
|
475 |
#endif
|
|
476 |
case 41: |
|
477 |
benchFunction = local_ZSTD_compressStream; benchName = "compressStream"; |
|
478 |
break; |
|
479 |
case 42: |
|
480 |
benchFunction = local_ZSTD_decompressStream; benchName = "decompressStream"; |
|
481 |
break; |
|
482 |
case 43: |
|
483 |
benchFunction = local_ZSTD_compressStream_freshCCtx; benchName = "compressStream_freshCCtx"; |
|
484 |
break; |
|
485 |
case 50: |
|
486 |
benchFunction = local_ZSTD_compress2; benchName = "compress2"; |
|
487 |
break; |
|
488 |
case 51: |
|
489 |
benchFunction = local_ZSTD_compressStream2_end; benchName = "compressStream2, end"; |
|
490 |
break; |
|
491 |
case 52: |
|
492 |
benchFunction = local_ZSTD_compressStream2_end; benchName = "compressStream2, end & short"; |
|
493 |
break; |
|
494 |
case 53: |
|
495 |
benchFunction = local_ZSTD_compressStream2_continue; benchName = "compressStream2, continue"; |
|
496 |
break; |
|
497 |
case 61: |
|
498 |
benchFunction = local_ZSTD_compress_generic_T2_continue; benchName = "compress_generic, -T2, continue"; |
|
499 |
break; |
|
500 |
case 62: |
|
501 |
benchFunction = local_ZSTD_compress_generic_T2_end; benchName = "compress_generic, -T2, end"; |
|
502 |
break; |
|
503 |
default : |
|
504 |
return 0; |
|
505 |
}
|
|
506 |
||
507 |
/* Allocation */
|
|
508 |
dstBuff = (BYTE*)malloc(dstBuffSize); |
|
509 |
dstBuff2 = malloc(dstBuffSize); |
|
510 |
if ((!dstBuff) || (!dstBuff2)) { |
|
511 |
DISPLAY("\nError: not enough memory!\n"); |
|
512 |
free(dstBuff); free(dstBuff2); |
|
513 |
return 12; |
|
514 |
}
|
|
515 |
payload = dstBuff2; |
|
516 |
if (g_zcc==NULL) g_zcc = ZSTD_createCCtx(); |
|
517 |
if (g_zdc==NULL) g_zdc = ZSTD_createDCtx(); |
|
518 |
if (g_cstream==NULL) g_cstream = ZSTD_createCStream(); |
|
519 |
if (g_dstream==NULL) g_dstream = ZSTD_createDStream(); |
|
520 |
||
521 |
/* DISPLAY("params: cLevel %d, wlog %d hlog %d clog %d slog %d mml %d tlen %d strat %d \n",
|
|
522 |
cLevel, cparams->windowLog, cparams->hashLog, cparams->chainLog, cparams->searchLog,
|
|
523 |
cparams->minMatch, cparams->targetLength, cparams->strategy); */
|
|
524 |
||
525 |
ZSTD_CCtx_setParameter(g_zcc, ZSTD_c_compressionLevel, cLevel); |
|
526 |
ZSTD_CCtx_setParameter(g_zcc, ZSTD_c_windowLog, (int)cparams.windowLog); |
|
527 |
ZSTD_CCtx_setParameter(g_zcc, ZSTD_c_hashLog, (int)cparams.hashLog); |
|
528 |
ZSTD_CCtx_setParameter(g_zcc, ZSTD_c_chainLog, (int)cparams.chainLog); |
|
529 |
ZSTD_CCtx_setParameter(g_zcc, ZSTD_c_searchLog, (int)cparams.searchLog); |
|
530 |
ZSTD_CCtx_setParameter(g_zcc, ZSTD_c_minMatch, (int)cparams.minMatch); |
|
531 |
ZSTD_CCtx_setParameter(g_zcc, ZSTD_c_targetLength, (int)cparams.targetLength); |
|
532 |
ZSTD_CCtx_setParameter(g_zcc, ZSTD_c_strategy, cparams.strategy); |
|
533 |
||
534 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_compressionLevel, cLevel); |
|
535 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_windowLog, (int)cparams.windowLog); |
|
536 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_hashLog, (int)cparams.hashLog); |
|
537 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_chainLog, (int)cparams.chainLog); |
|
538 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_searchLog, (int)cparams.searchLog); |
|
539 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_minMatch, (int)cparams.minMatch); |
|
540 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_targetLength, (int)cparams.targetLength); |
|
541 |
ZSTD_CCtx_setParameter(g_cstream, ZSTD_c_strategy, cparams.strategy); |
|
542 |
||
543 |
/* Preparation */
|
|
544 |
switch(benchNb) |
|
545 |
{
|
|
546 |
case 1: |
|
547 |
payload = &cparams; |
|
548 |
break; |
|
549 |
case 2: |
|
550 |
g_cSize = ZSTD_compress(dstBuff2, dstBuffSize, src, srcSize, cLevel); |
|
551 |
break; |
|
9
by mmach
152 |
552 |
case 3: |
553 |
payload = &cparams; |
|
554 |
break; |
|
1
by mmach
test 1 |
555 |
#ifndef ZSTD_DLL_IMPORT
|
556 |
case 11: |
|
557 |
payload = &cparams; |
|
558 |
break; |
|
559 |
case 12: |
|
560 |
payload = &cparams; |
|
561 |
break; |
|
562 |
case 13 : |
|
563 |
g_cSize = ZSTD_compress(dstBuff2, dstBuffSize, src, srcSize, cLevel); |
|
564 |
break; |
|
565 |
case 30: /* ZSTD_decodeLiteralsHeader */ |
|
566 |
/* fall-through */
|
|
567 |
case 31: /* ZSTD_decodeLiteralsBlock : starts literals block in dstBuff2 */ |
|
568 |
{ size_t frameHeaderSize; |
|
569 |
g_cSize = ZSTD_compress(dstBuff, dstBuffSize, src, srcSize, cLevel); |
|
570 |
frameHeaderSize = ZSTD_frameHeaderSize(dstBuff, ZSTD_FRAMEHEADERSIZE_PREFIX(ZSTD_f_zstd1)); |
|
571 |
CONTROL(!ZSTD_isError(frameHeaderSize)); |
|
572 |
/* check block is compressible, hence contains a literals section */
|
|
573 |
{ blockProperties_t bp; |
|
574 |
ZSTD_getcBlockSize(dstBuff+frameHeaderSize, dstBuffSize, &bp); /* Get 1st block type */ |
|
575 |
if (bp.blockType != bt_compressed) { |
|
576 |
DISPLAY("ZSTD_decodeLiteralsBlock : impossible to test on this sample (not compressible)\n"); |
|
577 |
goto _cleanOut; |
|
578 |
} } |
|
579 |
{ size_t const skippedSize = frameHeaderSize + ZSTD_blockHeaderSize; |
|
580 |
memcpy(dstBuff2, dstBuff+skippedSize, g_cSize-skippedSize); |
|
581 |
}
|
|
582 |
srcSize = srcSize > 128 KB ? 128 KB : srcSize; /* speed relative to block */ |
|
583 |
ZSTD_decompressBegin(g_zdc); |
|
584 |
break; |
|
585 |
}
|
|
586 |
case 32: /* ZSTD_decodeSeqHeaders */ |
|
587 |
{ blockProperties_t bp; |
|
588 |
const BYTE* ip = dstBuff; |
|
589 |
const BYTE* iend; |
|
590 |
{ size_t const cSize = ZSTD_compress(dstBuff, dstBuffSize, src, srcSize, cLevel); |
|
591 |
CONTROL(cSize > ZSTD_FRAMEHEADERSIZE_PREFIX(ZSTD_f_zstd1)); |
|
592 |
}
|
|
593 |
/* Skip frame Header */
|
|
594 |
{ size_t const frameHeaderSize = ZSTD_frameHeaderSize(dstBuff, ZSTD_FRAMEHEADERSIZE_PREFIX(ZSTD_f_zstd1)); |
|
595 |
CONTROL(!ZSTD_isError(frameHeaderSize)); |
|
596 |
ip += frameHeaderSize; |
|
597 |
}
|
|
598 |
/* Find end of block */
|
|
599 |
{ size_t const cBlockSize = ZSTD_getcBlockSize(ip, dstBuffSize, &bp); /* Get 1st block type */ |
|
600 |
if (bp.blockType != bt_compressed) { |
|
601 |
DISPLAY("ZSTD_decodeSeqHeaders : impossible to test on this sample (not compressible)\n"); |
|
602 |
goto _cleanOut; |
|
603 |
}
|
|
604 |
iend = ip + ZSTD_blockHeaderSize + cBlockSize; /* End of first block */ |
|
605 |
}
|
|
606 |
ip += ZSTD_blockHeaderSize; /* skip block header */ |
|
607 |
ZSTD_decompressBegin(g_zdc); |
|
608 |
CONTROL(iend > ip); |
|
9
by mmach
152 |
609 |
ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, (size_t)(iend-ip), dstBuff, dstBuffSize, not_streaming); /* skip literal segment */ |
1
by mmach
test 1 |
610 |
g_cSize = (size_t)(iend-ip); |
611 |
memcpy(dstBuff2, ip, g_cSize); /* copy rest of block (it starts by SeqHeader) */ |
|
612 |
srcSize = srcSize > 128 KB ? 128 KB : srcSize; /* speed relative to block */ |
|
613 |
break; |
|
614 |
}
|
|
615 |
#else
|
|
616 |
case 31: |
|
617 |
goto _cleanOut; |
|
618 |
#endif
|
|
619 |
case 41 : |
|
620 |
payload = &cparams; |
|
621 |
break; |
|
622 |
case 42 : |
|
623 |
g_cSize = ZSTD_compress(payload, dstBuffSize, src, srcSize, cLevel); |
|
624 |
break; |
|
625 |
case 43 : |
|
626 |
payload = &cparams; |
|
627 |
break; |
|
628 |
||
629 |
case 52 : |
|
630 |
/* compressStream2, short dstCapacity */
|
|
631 |
dstBuffSize--; |
|
632 |
break; |
|
633 |
||
634 |
/* test functions */
|
|
635 |
/* convention: test functions have ID > 100 */
|
|
636 |
||
637 |
default : ; |
|
638 |
}
|
|
639 |
||
640 |
/* warming up dstBuff */
|
|
641 |
{ size_t i; for (i=0; i<dstBuffSize; i++) dstBuff[i]=(BYTE)i; } |
|
642 |
||
643 |
/* benchmark loop */
|
|
644 |
{ BMK_timedFnState_t* const tfs = BMK_createTimedFnState(g_nbIterations * 1000, 1000); |
|
645 |
void* const avoidStrictAliasingPtr = &dstBuff; |
|
646 |
BMK_benchParams_t bp; |
|
647 |
BMK_runTime_t bestResult; |
|
648 |
bestResult.sumOfReturn = 0; |
|
649 |
bestResult.nanoSecPerRun = (double)TIMELOOP_NANOSEC * 2000000000; /* hopefully large enough : must be larger than any potential measurement */ |
|
650 |
CONTROL(tfs != NULL); |
|
651 |
||
652 |
bp.benchFn = benchFunction; |
|
653 |
bp.benchPayload = payload; |
|
654 |
bp.initFn = NULL; |
|
655 |
bp.initPayload = NULL; |
|
656 |
bp.errorFn = ZSTD_isError; |
|
657 |
bp.blockCount = 1; |
|
658 |
bp.srcBuffers = &src; |
|
659 |
bp.srcSizes = &srcSize; |
|
660 |
bp.dstBuffers = (void* const*) avoidStrictAliasingPtr; /* circumvent strict aliasing warning on gcc-8, |
|
661 |
* because gcc considers that `void* const *` and `void**` are 2 different types */
|
|
662 |
bp.dstCapacities = &dstBuffSize; |
|
663 |
bp.blockResults = NULL; |
|
664 |
||
665 |
for (;;) { |
|
666 |
BMK_runOutcome_t const bOutcome = BMK_benchTimedFn(tfs, bp); |
|
667 |
||
668 |
if (!BMK_isSuccessful_runOutcome(bOutcome)) { |
|
669 |
DISPLAY("ERROR benchmarking function ! ! \n"); |
|
670 |
errorcode = 1; |
|
671 |
goto _cleanOut; |
|
672 |
}
|
|
673 |
||
674 |
{ BMK_runTime_t const newResult = BMK_extract_runTime(bOutcome); |
|
675 |
if (newResult.nanoSecPerRun < bestResult.nanoSecPerRun ) |
|
676 |
bestResult.nanoSecPerRun = newResult.nanoSecPerRun; |
|
677 |
DISPLAY("\r%2u#%-29.29s:%8.1f MB/s (%8u) ", |
|
678 |
benchNb, benchName, |
|
679 |
(double)srcSize * TIMELOOP_NANOSEC / bestResult.nanoSecPerRun / MB_UNIT, |
|
680 |
(unsigned)newResult.sumOfReturn ); |
|
681 |
}
|
|
682 |
||
683 |
if ( BMK_isCompleted_TimedFn(tfs) ) break; |
|
684 |
}
|
|
685 |
BMK_freeTimedFnState(tfs); |
|
686 |
}
|
|
687 |
DISPLAY("\n"); |
|
688 |
||
689 |
_cleanOut: |
|
690 |
free(dstBuff); |
|
691 |
free(dstBuff2); |
|
692 |
ZSTD_freeCCtx(g_zcc); g_zcc=NULL; |
|
693 |
ZSTD_freeDCtx(g_zdc); g_zdc=NULL; |
|
694 |
ZSTD_freeCStream(g_cstream); g_cstream=NULL; |
|
695 |
ZSTD_freeDStream(g_dstream); g_dstream=NULL; |
|
696 |
return errorcode; |
|
697 |
}
|
|
698 |
||
699 |
||
700 |
static int benchSample(U32 benchNb, |
|
701 |
size_t benchedSize, double compressibility, |
|
702 |
int cLevel, ZSTD_compressionParameters cparams) |
|
703 |
{
|
|
704 |
/* Allocation */
|
|
705 |
void* const origBuff = malloc(benchedSize); |
|
706 |
if (!origBuff) { DISPLAY("\nError: not enough memory!\n"); return 12; } |
|
707 |
||
708 |
/* Fill buffer */
|
|
709 |
RDG_genBuffer(origBuff, benchedSize, compressibility, 0.0, 0); |
|
710 |
||
711 |
/* bench */
|
|
712 |
DISPLAY("\r%70s\r", ""); |
|
713 |
DISPLAY(" Sample %u bytes : \n", (unsigned)benchedSize); |
|
714 |
if (benchNb) { |
|
715 |
benchMem(benchNb, origBuff, benchedSize, cLevel, cparams); |
|
716 |
} else { /* 0 == run all tests */ |
|
717 |
for (benchNb=0; benchNb<100; benchNb++) { |
|
718 |
benchMem(benchNb, origBuff, benchedSize, cLevel, cparams); |
|
719 |
} } |
|
720 |
||
721 |
free(origBuff); |
|
722 |
return 0; |
|
723 |
}
|
|
724 |
||
725 |
||
726 |
static int benchFiles(U32 benchNb, |
|
727 |
const char** fileNamesTable, const int nbFiles, |
|
728 |
int cLevel, ZSTD_compressionParameters cparams) |
|
729 |
{
|
|
730 |
/* Loop for each file */
|
|
731 |
int fileIdx; |
|
732 |
for (fileIdx=0; fileIdx<nbFiles; fileIdx++) { |
|
733 |
const char* const inFileName = fileNamesTable[fileIdx]; |
|
734 |
FILE* const inFile = fopen( inFileName, "rb" ); |
|
735 |
size_t benchedSize; |
|
736 |
||
737 |
/* Check file existence */
|
|
738 |
if (inFile==NULL) { DISPLAY( "Pb opening %s\n", inFileName); return 11; } |
|
739 |
||
740 |
/* Memory allocation & restrictions */
|
|
741 |
{ U64 const inFileSize = UTIL_getFileSize(inFileName); |
|
742 |
if (inFileSize == UTIL_FILESIZE_UNKNOWN) { |
|
743 |
DISPLAY( "Cannot measure size of %s\n", inFileName); |
|
744 |
fclose(inFile); |
|
745 |
return 11; |
|
746 |
}
|
|
747 |
benchedSize = BMK_findMaxMem(inFileSize*3) / 3; |
|
748 |
if ((U64)benchedSize > inFileSize) |
|
749 |
benchedSize = (size_t)inFileSize; |
|
750 |
if ((U64)benchedSize < inFileSize) { |
|
751 |
DISPLAY("Not enough memory for '%s' full size; testing %u MB only... \n", |
|
752 |
inFileName, (unsigned)(benchedSize>>20)); |
|
753 |
} } |
|
754 |
||
755 |
/* Alloc */
|
|
756 |
{ void* const origBuff = malloc(benchedSize); |
|
757 |
if (!origBuff) { DISPLAY("\nError: not enough memory!\n"); fclose(inFile); return 12; } |
|
758 |
||
759 |
/* Fill input buffer */
|
|
760 |
DISPLAY("Loading %s... \r", inFileName); |
|
761 |
{ size_t const readSize = fread(origBuff, 1, benchedSize, inFile); |
|
762 |
fclose(inFile); |
|
763 |
if (readSize != benchedSize) { |
|
764 |
DISPLAY("\nError: problem reading file '%s' !! \n", inFileName); |
|
765 |
free(origBuff); |
|
766 |
return 13; |
|
767 |
} } |
|
768 |
||
769 |
/* bench */
|
|
770 |
DISPLAY("\r%70s\r", ""); /* blank line */ |
|
771 |
DISPLAY(" %s : \n", inFileName); |
|
772 |
if (benchNb) { |
|
773 |
benchMem(benchNb, origBuff, benchedSize, cLevel, cparams); |
|
774 |
} else { |
|
775 |
for (benchNb=0; benchNb<100; benchNb++) { |
|
776 |
benchMem(benchNb, origBuff, benchedSize, cLevel, cparams); |
|
19
by mmach
1.5.5 |
777 |
}
|
778 |
benchNb = 0; |
|
779 |
}
|
|
1
by mmach
test 1 |
780 |
|
781 |
free(origBuff); |
|
782 |
} } |
|
783 |
||
784 |
return 0; |
|
785 |
}
|
|
786 |
||
787 |
||
788 |
||
789 |
/*_*******************************************************
|
|
790 |
* Argument Parsing
|
|
791 |
*********************************************************/
|
|
792 |
||
793 |
#define ERROR_OUT(msg) { DISPLAY("%s \n", msg); exit(1); }
|
|
794 |
||
795 |
static unsigned readU32FromChar(const char** stringPtr) |
|
796 |
{
|
|
797 |
const char errorMsg[] = "error: numeric value too large"; |
|
798 |
unsigned result = 0; |
|
799 |
while ((**stringPtr >='0') && (**stringPtr <='9')) { |
|
800 |
unsigned const max = (((unsigned)(-1)) / 10) - 1; |
|
801 |
if (result > max) ERROR_OUT(errorMsg); |
|
802 |
result *= 10; |
|
803 |
result += (unsigned)(**stringPtr - '0'); |
|
804 |
(*stringPtr)++ ; |
|
805 |
}
|
|
806 |
if ((**stringPtr=='K') || (**stringPtr=='M')) { |
|
807 |
unsigned const maxK = ((unsigned)(-1)) >> 10; |
|
808 |
if (result > maxK) ERROR_OUT(errorMsg); |
|
809 |
result <<= 10; |
|
810 |
if (**stringPtr=='M') { |
|
811 |
if (result > maxK) ERROR_OUT(errorMsg); |
|
812 |
result <<= 10; |
|
813 |
}
|
|
814 |
(*stringPtr)++; /* skip `K` or `M` */ |
|
815 |
if (**stringPtr=='i') (*stringPtr)++; |
|
816 |
if (**stringPtr=='B') (*stringPtr)++; |
|
817 |
}
|
|
818 |
return result; |
|
819 |
}
|
|
820 |
||
821 |
static int longCommandWArg(const char** stringPtr, const char* longCommand) |
|
822 |
{
|
|
823 |
size_t const comSize = strlen(longCommand); |
|
824 |
int const result = !strncmp(*stringPtr, longCommand, comSize); |
|
825 |
if (result) *stringPtr += comSize; |
|
826 |
return result; |
|
827 |
}
|
|
828 |
||
829 |
||
830 |
/*_*******************************************************
|
|
831 |
* Command line
|
|
832 |
*********************************************************/
|
|
833 |
||
834 |
static int usage(const char* exename) |
|
835 |
{
|
|
836 |
DISPLAY( "Usage :\n"); |
|
837 |
DISPLAY( " %s [arg] file1 file2 ... fileX\n", exename); |
|
838 |
DISPLAY( "Arguments :\n"); |
|
839 |
DISPLAY( " -H/-h : Help (this text + advanced options)\n"); |
|
840 |
return 0; |
|
841 |
}
|
|
842 |
||
843 |
static int usage_advanced(const char* exename) |
|
844 |
{
|
|
845 |
usage(exename); |
|
846 |
DISPLAY( "\nAdvanced options :\n"); |
|
847 |
DISPLAY( " -b# : test only function # \n"); |
|
848 |
DISPLAY( " -l# : benchmark functions at that compression level (default : %i)\n", DEFAULT_CLEVEL); |
|
849 |
DISPLAY( "--zstd= : custom parameter selection. Format same as zstdcli \n"); |
|
850 |
DISPLAY( " -P# : sample compressibility (default : %.1f%%)\n", COMPRESSIBILITY_DEFAULT * 100); |
|
851 |
DISPLAY( " -B# : sample size (default : %u)\n", (unsigned)kSampleSizeDefault); |
|
852 |
DISPLAY( " -i# : iteration loops [1-9](default : %i)\n", NBLOOPS); |
|
853 |
return 0; |
|
854 |
}
|
|
855 |
||
856 |
static int badusage(const char* exename) |
|
857 |
{
|
|
858 |
DISPLAY("Wrong parameters\n"); |
|
859 |
usage(exename); |
|
860 |
return 1; |
|
861 |
}
|
|
862 |
||
863 |
int main(int argc, const char** argv) |
|
864 |
{
|
|
865 |
int argNb, filenamesStart=0, result; |
|
866 |
const char* const exename = argv[0]; |
|
867 |
const char* input_filename = NULL; |
|
868 |
U32 benchNb = 0, main_pause = 0; |
|
869 |
int cLevel = DEFAULT_CLEVEL; |
|
870 |
ZSTD_compressionParameters cparams = ZSTD_getCParams(cLevel, 0, 0); |
|
871 |
size_t sampleSize = kSampleSizeDefault; |
|
872 |
double compressibility = COMPRESSIBILITY_DEFAULT; |
|
873 |
||
874 |
DISPLAY(WELCOME_MESSAGE); |
|
875 |
if (argc<1) return badusage(exename); |
|
876 |
||
877 |
for (argNb=1; argNb<argc; argNb++) { |
|
878 |
const char* argument = argv[argNb]; |
|
879 |
CONTROL(argument != NULL); |
|
880 |
||
881 |
if (longCommandWArg(&argument, "--zstd=")) { |
|
882 |
for ( ; ;) { |
|
883 |
if (longCommandWArg(&argument, "windowLog=") || longCommandWArg(&argument, "wlog=")) { cparams.windowLog = readU32FromChar(&argument); if (argument[0]==',') { argument++; continue; } else break; } |
|
884 |
if (longCommandWArg(&argument, "chainLog=") || longCommandWArg(&argument, "clog=")) { cparams.chainLog = readU32FromChar(&argument); if (argument[0]==',') { argument++; continue; } else break; } |
|
885 |
if (longCommandWArg(&argument, "hashLog=") || longCommandWArg(&argument, "hlog=")) { cparams.hashLog = readU32FromChar(&argument); if (argument[0]==',') { argument++; continue; } else break; } |
|
886 |
if (longCommandWArg(&argument, "searchLog=") || longCommandWArg(&argument, "slog=")) { cparams.searchLog = readU32FromChar(&argument); if (argument[0]==',') { argument++; continue; } else break; } |
|
887 |
if (longCommandWArg(&argument, "minMatch=") || longCommandWArg(&argument, "mml=")) { cparams.minMatch = readU32FromChar(&argument); if (argument[0]==',') { argument++; continue; } else break; } |
|
888 |
if (longCommandWArg(&argument, "targetLength=") || longCommandWArg(&argument, "tlen=")) { cparams.targetLength = readU32FromChar(&argument); if (argument[0]==',') { argument++; continue; } else break; } |
|
889 |
if (longCommandWArg(&argument, "strategy=") || longCommandWArg(&argument, "strat=")) { cparams.strategy = (ZSTD_strategy)(readU32FromChar(&argument)); if (argument[0]==',') { argument++; continue; } else break; } |
|
890 |
if (longCommandWArg(&argument, "level=") || longCommandWArg(&argument, "lvl=")) { cLevel = (int)readU32FromChar(&argument); cparams = ZSTD_getCParams(cLevel, 0, 0); if (argument[0]==',') { argument++; continue; } else break; } |
|
891 |
DISPLAY("invalid compression parameter \n"); |
|
892 |
return 1; |
|
893 |
}
|
|
894 |
||
895 |
/* check end of string */
|
|
896 |
if (argument[0] != 0) { |
|
897 |
DISPLAY("invalid --zstd= format \n"); |
|
898 |
return 1; |
|
899 |
} else { |
|
900 |
continue; |
|
901 |
}
|
|
902 |
||
903 |
} else if (argument[0]=='-') { /* Commands (note : aggregated commands are allowed) */ |
|
904 |
argument++; |
|
905 |
while (argument[0]!=0) { |
|
906 |
||
907 |
switch(argument[0]) |
|
908 |
{
|
|
909 |
/* Display help on usage */
|
|
910 |
case 'h': |
|
911 |
case 'H': return usage_advanced(exename); |
|
912 |
||
913 |
/* Pause at the end (hidden option) */
|
|
914 |
case 'p': main_pause = 1; break; |
|
915 |
||
916 |
/* Select specific algorithm to bench */
|
|
917 |
case 'b': |
|
918 |
argument++; |
|
919 |
benchNb = readU32FromChar(&argument); |
|
920 |
break; |
|
921 |
||
922 |
/* Select compression level to use */
|
|
923 |
case 'l': |
|
924 |
argument++; |
|
925 |
cLevel = (int)readU32FromChar(&argument); |
|
926 |
cparams = ZSTD_getCParams(cLevel, 0, 0); |
|
927 |
break; |
|
928 |
||
929 |
/* Select compressibility of synthetic sample */
|
|
930 |
case 'P': |
|
931 |
argument++; |
|
932 |
compressibility = (double)readU32FromChar(&argument) / 100.; |
|
933 |
break; |
|
934 |
||
935 |
/* Select size of synthetic sample */
|
|
936 |
case 'B': |
|
937 |
argument++; |
|
938 |
sampleSize = (size_t)readU32FromChar(&argument); |
|
939 |
break; |
|
940 |
||
941 |
/* Modify Nb Iterations */
|
|
942 |
case 'i': |
|
943 |
argument++; |
|
944 |
g_nbIterations = readU32FromChar(&argument); |
|
945 |
break; |
|
946 |
||
947 |
/* Unknown command */
|
|
948 |
default : return badusage(exename); |
|
949 |
}
|
|
950 |
}
|
|
951 |
continue; |
|
952 |
}
|
|
953 |
||
954 |
/* first provided filename is input */
|
|
955 |
if (!input_filename) { input_filename=argument; filenamesStart=argNb; continue; } |
|
956 |
}
|
|
957 |
||
958 |
||
959 |
||
960 |
if (filenamesStart==0) /* no input file */ |
|
961 |
result = benchSample(benchNb, sampleSize, compressibility, cLevel, cparams); |
|
962 |
else
|
|
963 |
result = benchFiles(benchNb, argv+filenamesStart, argc-filenamesStart, cLevel, cparams); |
|
964 |
||
965 |
if (main_pause) { int unused; printf("press enter...\n"); unused = getchar(); (void)unused; } |
|
966 |
||
967 |
return result; |
|
968 |
}
|