Merge branch 'dev' of github.com:facebook/zstd into dev
This commit is contained in:
commit
e45d82ab0b
@ -192,6 +192,8 @@ typedef struct {
|
|||||||
BYTE* llCode;
|
BYTE* llCode;
|
||||||
BYTE* mlCode;
|
BYTE* mlCode;
|
||||||
BYTE* ofCode;
|
BYTE* ofCode;
|
||||||
|
size_t maxNbSeq;
|
||||||
|
size_t maxNbLit;
|
||||||
U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
|
U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
|
||||||
U32 longLengthPos;
|
U32 longLengthPos;
|
||||||
} seqStore_t;
|
} seqStore_t;
|
||||||
|
@ -805,7 +805,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|||||||
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
|
||||||
U32 const divider = (cParams.searchLength==3) ? 3 : 4;
|
U32 const divider = (cParams.searchLength==3) ? 3 : 4;
|
||||||
size_t const maxNbSeq = blockSize / divider;
|
size_t const maxNbSeq = blockSize / divider;
|
||||||
size_t const tokenSpace = blockSize + 11*maxNbSeq;
|
size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
|
||||||
size_t const entropySpace = HUF_WORKSPACE_SIZE;
|
size_t const entropySpace = HUF_WORKSPACE_SIZE;
|
||||||
size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
|
size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
|
||||||
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
|
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
|
||||||
@ -931,33 +931,51 @@ typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
|
|||||||
/* ZSTD_sufficientBuff() :
|
/* ZSTD_sufficientBuff() :
|
||||||
* check internal buffers exist for streaming if buffPol == ZSTDb_buffered .
|
* check internal buffers exist for streaming if buffPol == ZSTDb_buffered .
|
||||||
* Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */
|
* Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */
|
||||||
static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t blockSize1,
|
static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t maxNbSeq1,
|
||||||
|
size_t maxNbLit1,
|
||||||
ZSTD_buffered_policy_e buffPol2,
|
ZSTD_buffered_policy_e buffPol2,
|
||||||
ZSTD_compressionParameters cParams2,
|
ZSTD_compressionParameters cParams2,
|
||||||
U64 pledgedSrcSize)
|
U64 pledgedSrcSize)
|
||||||
{
|
{
|
||||||
size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
|
size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
|
||||||
size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
|
size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
|
||||||
|
size_t const maxNbSeq2 = blockSize2 / ((cParams2.searchLength == 3) ? 3 : 4);
|
||||||
|
size_t const maxNbLit2 = blockSize2;
|
||||||
size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
|
size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
|
||||||
DEBUGLOG(4, "ZSTD_sufficientBuff: is windowSize2=%u <= wlog1=%u",
|
DEBUGLOG(4, "ZSTD_sufficientBuff: is neededBufferSize2=%u <= bufferSize1=%u",
|
||||||
(U32)windowSize2, cParams2.windowLog);
|
(U32)neededBufferSize2, (U32)bufferSize1);
|
||||||
DEBUGLOG(4, "ZSTD_sufficientBuff: is blockSize2=%u <= blockSize1=%u",
|
DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbSeq2=%u <= maxNbSeq1=%u",
|
||||||
(U32)blockSize2, (U32)blockSize1);
|
(U32)maxNbSeq2, (U32)maxNbSeq1);
|
||||||
return (blockSize2 <= blockSize1) /* seqStore space depends on blockSize */
|
DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbLit2=%u <= maxNbLit1=%u",
|
||||||
|
(U32)maxNbLit2, (U32)maxNbLit1);
|
||||||
|
return (maxNbLit2 <= maxNbLit1)
|
||||||
|
& (maxNbSeq2 <= maxNbSeq1)
|
||||||
& (neededBufferSize2 <= bufferSize1);
|
& (neededBufferSize2 <= bufferSize1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Equivalence for resetCCtx purposes */
|
/** Equivalence for resetCCtx purposes */
|
||||||
static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
|
static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
|
||||||
ZSTD_CCtx_params params2,
|
ZSTD_CCtx_params params2,
|
||||||
size_t buffSize1, size_t blockSize1,
|
size_t buffSize1,
|
||||||
|
size_t maxNbSeq1, size_t maxNbLit1,
|
||||||
ZSTD_buffered_policy_e buffPol2,
|
ZSTD_buffered_policy_e buffPol2,
|
||||||
U64 pledgedSrcSize)
|
U64 pledgedSrcSize)
|
||||||
{
|
{
|
||||||
DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize);
|
DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize);
|
||||||
return ZSTD_equivalentCParams(params1.cParams, params2.cParams) &&
|
if (!ZSTD_equivalentCParams(params1.cParams, params2.cParams)) {
|
||||||
ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams) &&
|
DEBUGLOG(4, "ZSTD_equivalentCParams() == 0");
|
||||||
ZSTD_sufficientBuff(buffSize1, blockSize1, buffPol2, params2.cParams, pledgedSrcSize);
|
return 0;
|
||||||
|
}
|
||||||
|
if (!ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams)) {
|
||||||
|
DEBUGLOG(4, "ZSTD_equivalentLdmParams() == 0");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!ZSTD_sufficientBuff(buffSize1, maxNbSeq1, maxNbLit1, buffPol2,
|
||||||
|
params2.cParams, pledgedSrcSize)) {
|
||||||
|
DEBUGLOG(4, "ZSTD_sufficientBuff() == 0");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
|
static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
|
||||||
@ -1085,8 +1103,9 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|||||||
|
|
||||||
if (crp == ZSTDcrp_continue) {
|
if (crp == ZSTDcrp_continue) {
|
||||||
if (ZSTD_equivalentParams(zc->appliedParams, params,
|
if (ZSTD_equivalentParams(zc->appliedParams, params,
|
||||||
zc->inBuffSize, zc->blockSize,
|
zc->inBuffSize,
|
||||||
zbuff, pledgedSrcSize)) {
|
zc->seqStore.maxNbSeq, zc->seqStore.maxNbLit,
|
||||||
|
zbuff, pledgedSrcSize)) {
|
||||||
DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)",
|
DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)",
|
||||||
zc->appliedParams.cParams.windowLog, zc->blockSize);
|
zc->appliedParams.cParams.windowLog, zc->blockSize);
|
||||||
zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0); /* if it was too large, it still is */
|
zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0); /* if it was too large, it still is */
|
||||||
@ -1107,7 +1126,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|||||||
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
|
||||||
U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
|
U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
|
||||||
size_t const maxNbSeq = blockSize / divider;
|
size_t const maxNbSeq = blockSize / divider;
|
||||||
size_t const tokenSpace = blockSize + 11*maxNbSeq;
|
size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
|
||||||
size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
|
size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
|
||||||
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
|
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
|
||||||
size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1);
|
size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1);
|
||||||
@ -1197,13 +1216,18 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|||||||
ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, ¶ms.cParams, crp, /* forCCtx */ 1);
|
ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, ¶ms.cParams, crp, /* forCCtx */ 1);
|
||||||
|
|
||||||
/* sequences storage */
|
/* sequences storage */
|
||||||
|
zc->seqStore.maxNbSeq = maxNbSeq;
|
||||||
zc->seqStore.sequencesStart = (seqDef*)ptr;
|
zc->seqStore.sequencesStart = (seqDef*)ptr;
|
||||||
ptr = zc->seqStore.sequencesStart + maxNbSeq;
|
ptr = zc->seqStore.sequencesStart + maxNbSeq;
|
||||||
zc->seqStore.llCode = (BYTE*) ptr;
|
zc->seqStore.llCode = (BYTE*) ptr;
|
||||||
zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
|
zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
|
||||||
zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
|
zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
|
||||||
zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
|
zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
|
||||||
ptr = zc->seqStore.litStart + blockSize;
|
/* ZSTD_wildcopy() is used to copy into the literals buffer,
|
||||||
|
* so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes.
|
||||||
|
*/
|
||||||
|
zc->seqStore.maxNbLit = blockSize;
|
||||||
|
ptr = zc->seqStore.litStart + blockSize + WILDCOPY_OVERLENGTH;
|
||||||
|
|
||||||
/* ldm bucketOffsets table */
|
/* ldm bucketOffsets table */
|
||||||
if (params.ldmParams.enableLdm) {
|
if (params.ldmParams.enableLdm) {
|
||||||
@ -1322,8 +1346,7 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy dictionary offsets */
|
/* copy dictionary offsets */
|
||||||
{
|
{ ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
|
||||||
ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
|
|
||||||
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
|
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
|
||||||
dstMatchState->window = srcMatchState->window;
|
dstMatchState->window = srcMatchState->window;
|
||||||
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
||||||
@ -1647,6 +1670,7 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
|
|||||||
BYTE* const mlCodeTable = seqStorePtr->mlCode;
|
BYTE* const mlCodeTable = seqStorePtr->mlCode;
|
||||||
U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
||||||
U32 u;
|
U32 u;
|
||||||
|
assert(nbSeq <= seqStorePtr->maxNbSeq);
|
||||||
for (u=0; u<nbSeq; u++) {
|
for (u=0; u<nbSeq; u++) {
|
||||||
U32 const llv = sequences[u].litLength;
|
U32 const llv = sequences[u].litLength;
|
||||||
U32 const mlv = sequences[u].matchLength;
|
U32 const mlv = sequences[u].matchLength;
|
||||||
@ -2235,13 +2259,6 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
|
|||||||
if (cSize >= maxCSize) return 0; /* block not compressed */
|
if (cSize >= maxCSize) return 0; /* block not compressed */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We check that dictionaries have offset codes available for the first
|
|
||||||
* block. After the first block, the offcode table might not have large
|
|
||||||
* enough codes to represent the offsets in the data.
|
|
||||||
*/
|
|
||||||
if (nextEntropy->fse.offcode_repeatMode == FSE_repeat_valid)
|
|
||||||
nextEntropy->fse.offcode_repeatMode = FSE_repeat_check;
|
|
||||||
|
|
||||||
return cSize;
|
return cSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2380,12 +2397,20 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
|||||||
&zc->appliedParams,
|
&zc->appliedParams,
|
||||||
dst, dstCapacity,
|
dst, dstCapacity,
|
||||||
srcSize, zc->entropyWorkspace, zc->bmi2);
|
srcSize, zc->entropyWorkspace, zc->bmi2);
|
||||||
if (ZSTD_isError(cSize) || cSize == 0) return cSize;
|
if (!ZSTD_isError(cSize) && cSize != 0) {
|
||||||
/* confirm repcodes and entropy tables */
|
/* confirm repcodes and entropy tables */
|
||||||
{ ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
|
ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
|
||||||
zc->blockState.prevCBlock = zc->blockState.nextCBlock;
|
zc->blockState.prevCBlock = zc->blockState.nextCBlock;
|
||||||
zc->blockState.nextCBlock = tmp;
|
zc->blockState.nextCBlock = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We check that dictionaries have offset codes available for the first
|
||||||
|
* block. After the first block, the offcode table might not have large
|
||||||
|
* enough codes to represent the offsets in the data.
|
||||||
|
*/
|
||||||
|
if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
|
||||||
|
zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
|
||||||
|
|
||||||
return cSize;
|
return cSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,8 +314,10 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
|
|||||||
pos, (U32)litLength, (U32)mlBase+MINMATCH, (U32)offsetCode);
|
pos, (U32)litLength, (U32)mlBase+MINMATCH, (U32)offsetCode);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq);
|
||||||
/* copy Literals */
|
/* copy Literals */
|
||||||
assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + 128 KB);
|
assert(seqStorePtr->maxNbLit <= 128 KB);
|
||||||
|
assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit);
|
||||||
ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
|
ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
|
||||||
seqStorePtr->lit += litLength;
|
seqStorePtr->lit += litLength;
|
||||||
|
|
||||||
|
@ -987,8 +987,10 @@ size_t ZDICT_trainFromBuffer_unsafe_legacy(
|
|||||||
U32 const pos = dictList[u].pos;
|
U32 const pos = dictList[u].pos;
|
||||||
U32 const length = dictList[u].length;
|
U32 const length = dictList[u].length;
|
||||||
U32 const printedLength = MIN(40, length);
|
U32 const printedLength = MIN(40, length);
|
||||||
if ((pos > samplesBuffSize) || ((pos + length) > samplesBuffSize))
|
if ((pos > samplesBuffSize) || ((pos + length) > samplesBuffSize)) {
|
||||||
|
free(dictList);
|
||||||
return ERROR(GENERIC); /* should never happen */
|
return ERROR(GENERIC); /* should never happen */
|
||||||
|
}
|
||||||
DISPLAYLEVEL(3, "%3u:%3u bytes at pos %8u, savings %7u bytes |",
|
DISPLAYLEVEL(3, "%3u:%3u bytes at pos %8u, savings %7u bytes |",
|
||||||
u, length, pos, dictList[u].savings);
|
u, length, pos, dictList[u].savings);
|
||||||
ZDICT_printHex((const char*)samplesBuffer+pos, printedLength);
|
ZDICT_printHex((const char*)samplesBuffer+pos, printedLength);
|
||||||
|
@ -211,7 +211,8 @@ typedef struct ZSTD_CDict_s ZSTD_CDict;
|
|||||||
* When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once.
|
* When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once.
|
||||||
* ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
|
* ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
|
||||||
* ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only.
|
* ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only.
|
||||||
* `dictBuffer` can be released after ZSTD_CDict creation, since its content is copied within CDict */
|
* `dictBuffer` can be released after ZSTD_CDict creation, since its content is copied within CDict
|
||||||
|
* Note : A ZSTD_CDict can be created with an empty dictionary, but it is inefficient for small data. */
|
||||||
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize,
|
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize,
|
||||||
int compressionLevel);
|
int compressionLevel);
|
||||||
|
|
||||||
@ -223,7 +224,9 @@ ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
|
|||||||
* Compression using a digested Dictionary.
|
* Compression using a digested Dictionary.
|
||||||
* Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
|
* Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
|
||||||
* Note that compression level is decided during dictionary creation.
|
* Note that compression level is decided during dictionary creation.
|
||||||
* Frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no) */
|
* Frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no)
|
||||||
|
* Note : ZSTD_compress_usingCDict() can be used with a ZSTD_CDict created from an empty dictionary.
|
||||||
|
* But it is inefficient for small data, and it is recommended to use ZSTD_compressCCtx(). */
|
||||||
ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
|
ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
|
984
programs/bench.c
984
programs/bench.c
File diff suppressed because it is too large
Load Diff
340
programs/bench.h
340
programs/bench.h
@ -15,59 +15,82 @@ extern "C" {
|
|||||||
#ifndef BENCH_H_121279284357
|
#ifndef BENCH_H_121279284357
|
||||||
#define BENCH_H_121279284357
|
#define BENCH_H_121279284357
|
||||||
|
|
||||||
|
/* === Dependencies === */
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */
|
||||||
#include "zstd.h" /* ZSTD_compressionParameters */
|
#include "zstd.h" /* ZSTD_compressionParameters */
|
||||||
|
|
||||||
/* Creates a struct of type typeName with an int type .error field
|
|
||||||
* and a .result field of some baseType. Functions with return
|
/* === Constants === */
|
||||||
* typeName pass a successful result with .error = 0 and .result
|
|
||||||
* with the intended result, while returning an error will result
|
#define MB_UNIT 1000000
|
||||||
* in .error != 0.
|
|
||||||
|
|
||||||
|
/* === Benchmark functions === */
|
||||||
|
|
||||||
|
/* Creates a variant `typeName`, able to express "error or valid result".
|
||||||
|
* Functions with return type `typeName`
|
||||||
|
* must first check if result is valid, using BMK_isSuccessful_*(),
|
||||||
|
* and only then can extract `baseType`.
|
||||||
*/
|
*/
|
||||||
#define ERROR_STRUCT(baseType, typeName) typedef struct { \
|
#define VARIANT_ERROR_RESULT(baseType, variantName) \
|
||||||
baseType result; \
|
\
|
||||||
int error; \
|
typedef struct { \
|
||||||
} typeName
|
baseType internal_never_use_directly; \
|
||||||
|
int tag; \
|
||||||
|
} variantName
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t cSize;
|
size_t cSize;
|
||||||
U64 cSpeed; /* bytes / sec */
|
unsigned long long cSpeed; /* bytes / sec */
|
||||||
U64 dSpeed;
|
unsigned long long dSpeed;
|
||||||
size_t cMem;
|
size_t cMem; /* ? what is reported ? */
|
||||||
} BMK_result_t;
|
} BMK_benchResult_t;
|
||||||
|
|
||||||
ERROR_STRUCT(BMK_result_t, BMK_return_t);
|
VARIANT_ERROR_RESULT(BMK_benchResult_t, BMK_benchOutcome_t);
|
||||||
|
|
||||||
/* called in cli */
|
/* check first if the return structure represents an error or a valid result */
|
||||||
/* Loads files in fileNamesTable into memory, as well as a dictionary
|
int BMK_isSuccessful_benchOutcome(BMK_benchOutcome_t outcome);
|
||||||
* from dictFileName, and then uses benchMem */
|
|
||||||
/* fileNamesTable - name of files to benchmark
|
/* extract result from variant type.
|
||||||
* nbFiles - number of files (size of fileNamesTable), must be > 0
|
* note : this function will abort() program execution if result is not valid
|
||||||
* dictFileName - name of dictionary file to load
|
* check result validity first, by using BMK_isSuccessful_benchOutcome()
|
||||||
* cLevel - compression level to benchmark, errors if invalid
|
|
||||||
* compressionParams - basic compression Parameters
|
|
||||||
* displayLevel - what gets printed
|
|
||||||
* 0 : no display;
|
|
||||||
* 1 : errors;
|
|
||||||
* 2 : + result + interaction + warnings;
|
|
||||||
* 3 : + progression;
|
|
||||||
* 4 : + information
|
|
||||||
* return
|
|
||||||
* .error will give a nonzero error value if an error has occured
|
|
||||||
* .result - if .error = 0, .result will return the time taken to compression speed
|
|
||||||
* (.cSpeed), decompression speed (.dSpeed), and compressed size (.cSize) of the original
|
|
||||||
* file
|
|
||||||
*/
|
*/
|
||||||
BMK_return_t BMK_benchFiles(const char* const * const fileNamesTable, unsigned const nbFiles,
|
BMK_benchResult_t BMK_extract_benchResult(BMK_benchOutcome_t outcome);
|
||||||
const char* const dictFileName,
|
|
||||||
int const cLevel, const ZSTD_compressionParameters* const compressionParams,
|
|
||||||
|
/*! BMK_benchFiles() -- called by zstdcli */
|
||||||
|
/* Loads files from fileNamesTable into memory,
|
||||||
|
* and an optional dictionary from dictFileName (can be NULL),
|
||||||
|
* then uses benchMem().
|
||||||
|
* fileNamesTable - name of files to benchmark.
|
||||||
|
* nbFiles - number of files (size of fileNamesTable), must be > 0.
|
||||||
|
* dictFileName - name of dictionary file to load.
|
||||||
|
* cLevel - compression level to benchmark, errors if invalid.
|
||||||
|
* compressionParams - advanced compression Parameters.
|
||||||
|
* displayLevel - what gets printed:
|
||||||
|
* 0 : no display;
|
||||||
|
* 1 : errors;
|
||||||
|
* 2 : + result + interaction + warnings;
|
||||||
|
* 3 : + information;
|
||||||
|
* 4 : + debug
|
||||||
|
* @return:
|
||||||
|
* a variant, which expresses either an error, or a valid result.
|
||||||
|
* Use BMK_isSuccessful_benchOutcome() to check if function was successful.
|
||||||
|
* If yes, extract the valid result with BMK_extract_benchResult(),
|
||||||
|
* it will contain :
|
||||||
|
* .cSpeed: compression speed in bytes per second,
|
||||||
|
* .dSpeed: decompression speed in bytes per second,
|
||||||
|
* .cSize : compressed size, in bytes
|
||||||
|
* .cMem : memory budget required for the compression context
|
||||||
|
*/
|
||||||
|
BMK_benchOutcome_t BMK_benchFiles(
|
||||||
|
const char* const * fileNamesTable, unsigned nbFiles,
|
||||||
|
const char* dictFileName,
|
||||||
|
int cLevel, const ZSTD_compressionParameters* compressionParams,
|
||||||
int displayLevel);
|
int displayLevel);
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BMK_timeMode = 0,
|
|
||||||
BMK_iterMode = 1
|
|
||||||
} BMK_loopMode_t;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
BMK_both = 0,
|
BMK_both = 0,
|
||||||
@ -77,15 +100,14 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BMK_mode_t mode; /* 0: all, 1: compress only 2: decode only */
|
BMK_mode_t mode; /* 0: all, 1: compress only 2: decode only */
|
||||||
BMK_loopMode_t loopMode; /* if loopmode, then nbSeconds = nbLoops */
|
|
||||||
unsigned nbSeconds; /* default timing is in nbSeconds */
|
unsigned nbSeconds; /* default timing is in nbSeconds */
|
||||||
size_t blockSize; /* Maximum allowable size of a block*/
|
size_t blockSize; /* Maximum size of each block*/
|
||||||
unsigned nbWorkers; /* multithreading */
|
unsigned nbWorkers; /* multithreading */
|
||||||
unsigned realTime; /* real time priority */
|
unsigned realTime; /* real time priority */
|
||||||
int additionalParam; /* used by python speed benchmark */
|
int additionalParam; /* used by python speed benchmark */
|
||||||
unsigned ldmFlag; /* enables long distance matching */
|
unsigned ldmFlag; /* enables long distance matching */
|
||||||
unsigned ldmMinMatch; /* below: parameters for long distance matching, see zstd.1.md for meaning */
|
unsigned ldmMinMatch; /* below: parameters for long distance matching, see zstd.1.md */
|
||||||
unsigned ldmHashLog;
|
unsigned ldmHashLog;
|
||||||
unsigned ldmBucketSizeLog;
|
unsigned ldmBucketSizeLog;
|
||||||
unsigned ldmHashEveryLog;
|
unsigned ldmHashEveryLog;
|
||||||
} BMK_advancedParams_t;
|
} BMK_advancedParams_t;
|
||||||
@ -93,132 +115,186 @@ typedef struct {
|
|||||||
/* returns default parameters used by nonAdvanced functions */
|
/* returns default parameters used by nonAdvanced functions */
|
||||||
BMK_advancedParams_t BMK_initAdvancedParams(void);
|
BMK_advancedParams_t BMK_initAdvancedParams(void);
|
||||||
|
|
||||||
/* See benchFiles for normal parameter uses and return, see advancedParams_t for adv */
|
/*! BMK_benchFilesAdvanced():
|
||||||
BMK_return_t BMK_benchFilesAdvanced(const char* const * const fileNamesTable, unsigned const nbFiles,
|
* Same as BMK_benchFiles(),
|
||||||
const char* const dictFileName,
|
* with more controls, provided through advancedParams_t structure */
|
||||||
int const cLevel, const ZSTD_compressionParameters* const compressionParams,
|
BMK_benchOutcome_t BMK_benchFilesAdvanced(
|
||||||
int displayLevel, const BMK_advancedParams_t* const adv);
|
const char* const * fileNamesTable, unsigned nbFiles,
|
||||||
|
const char* dictFileName,
|
||||||
|
int cLevel, const ZSTD_compressionParameters* compressionParams,
|
||||||
|
int displayLevel, const BMK_advancedParams_t* adv);
|
||||||
|
|
||||||
/* called in cli */
|
/*! BMK_syntheticTest() -- called from zstdcli */
|
||||||
/* Generates a sample with datagen with the compressibility argument*/
|
/* Generates a sample with datagen, using compressibility argument */
|
||||||
/* cLevel - compression level to benchmark, errors if invalid
|
/* cLevel - compression level to benchmark, errors if invalid
|
||||||
* compressibility - determines compressibility of sample
|
* compressibility - determines compressibility of sample
|
||||||
* compressionParams - basic compression Parameters
|
* compressionParams - basic compression Parameters
|
||||||
* displayLevel - see benchFiles
|
* displayLevel - see benchFiles
|
||||||
* adv - see advanced_Params_t
|
* adv - see advanced_Params_t
|
||||||
* return
|
* @return:
|
||||||
* .error will give a nonzero error value if an error has occured
|
* a variant, which expresses either an error, or a valid result.
|
||||||
* .result - if .error = 0, .result will return the time taken to compression speed
|
* Use BMK_isSuccessful_benchOutcome() to check if function was successful.
|
||||||
* (.cSpeed), decompression speed (.dSpeed), and compressed size (.cSize) of the original
|
* If yes, extract the valid result with BMK_extract_benchResult(),
|
||||||
* file
|
* it will contain :
|
||||||
|
* .cSpeed: compression speed in bytes per second,
|
||||||
|
* .dSpeed: decompression speed in bytes per second,
|
||||||
|
* .cSize : compressed size, in bytes
|
||||||
|
* .cMem : memory budget required for the compression context
|
||||||
*/
|
*/
|
||||||
BMK_return_t BMK_syntheticTest(int cLevel, double compressibility,
|
BMK_benchOutcome_t BMK_syntheticTest(
|
||||||
|
int cLevel, double compressibility,
|
||||||
const ZSTD_compressionParameters* compressionParams,
|
const ZSTD_compressionParameters* compressionParams,
|
||||||
int displayLevel, const BMK_advancedParams_t * const adv);
|
int displayLevel, const BMK_advancedParams_t* adv);
|
||||||
|
|
||||||
/* basic benchmarking function, called in paramgrill
|
|
||||||
* applies ZSTD_compress_generic() and ZSTD_decompress_generic() on data in srcBuffer
|
|
||||||
* with specific compression parameters specified by other arguments using benchFunction
|
/* === Benchmark Zstandard in a memory-to-memory scenario === */
|
||||||
* (cLevel, comprParams + adv in advanced Mode) */
|
|
||||||
/* srcBuffer - data source, expected to be valid compressed data if in Decode Only Mode
|
/** BMK_benchMem() -- core benchmarking function, called in paramgrill
|
||||||
* srcSize - size of data in srcBuffer
|
* applies ZSTD_compress_generic() and ZSTD_decompress_generic() on data in srcBuffer
|
||||||
* cLevel - compression level
|
* with specific compression parameters provided by other arguments using benchFunction
|
||||||
* comprParams - basic compression parameters
|
* (cLevel, comprParams + adv in advanced Mode) */
|
||||||
* dictBuffer - a dictionary if used, null otherwise
|
/* srcBuffer - data source, expected to be valid compressed data if in Decode Only Mode
|
||||||
* dictBufferSize - size of dictBuffer, 0 otherwise
|
* srcSize - size of data in srcBuffer
|
||||||
* diplayLevel - see BMK_benchFiles
|
* fileSizes - srcBuffer is considered cut into 1+ segments, to compress separately.
|
||||||
* displayName - name used by display
|
* note : sum(fileSizes) must be == srcSize. (<== ensure it's properly checked)
|
||||||
* return
|
* nbFiles - nb of segments
|
||||||
* .error will give a nonzero value if an error has occured
|
* cLevel - compression level
|
||||||
* .result - if .error = 0, will give the same results as benchFiles
|
* comprParams - basic compression parameters
|
||||||
* but for the data stored in srcBuffer
|
* dictBuffer - a dictionary if used, null otherwise
|
||||||
|
* dictBufferSize - size of dictBuffer, 0 otherwise
|
||||||
|
* diplayLevel - see BMK_benchFiles
|
||||||
|
* displayName - name used by display
|
||||||
|
* @return:
|
||||||
|
* a variant, which expresses either an error, or a valid result.
|
||||||
|
* Use BMK_isSuccessful_benchOutcome() to check if function was successful.
|
||||||
|
* If yes, extract the valid result with BMK_extract_benchResult(),
|
||||||
|
* it will contain :
|
||||||
|
* .cSpeed: compression speed in bytes per second,
|
||||||
|
* .dSpeed: decompression speed in bytes per second,
|
||||||
|
* .cSize : compressed size, in bytes
|
||||||
|
* .cMem : memory budget required for the compression context
|
||||||
*/
|
*/
|
||||||
BMK_return_t BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
BMK_benchOutcome_t BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
||||||
const size_t* fileSizes, unsigned nbFiles,
|
const size_t* fileSizes, unsigned nbFiles,
|
||||||
const int cLevel, const ZSTD_compressionParameters* comprParams,
|
int cLevel, const ZSTD_compressionParameters* comprParams,
|
||||||
const void* dictBuffer, size_t dictBufferSize,
|
const void* dictBuffer, size_t dictBufferSize,
|
||||||
int displayLevel, const char* displayName);
|
int displayLevel, const char* displayName);
|
||||||
|
|
||||||
/* See benchMem for normal parameter uses and return, see advancedParams_t for adv
|
/* BMK_benchMemAdvanced() : same as BMK_benchMem()
|
||||||
|
* with following additional options :
|
||||||
* dstBuffer - destination buffer to write compressed output in, NULL if none provided.
|
* dstBuffer - destination buffer to write compressed output in, NULL if none provided.
|
||||||
* dstCapacity - capacity of destination buffer, give 0 if dstBuffer = NULL
|
* dstCapacity - capacity of destination buffer, give 0 if dstBuffer = NULL
|
||||||
|
* adv = see advancedParams_t
|
||||||
*/
|
*/
|
||||||
BMK_return_t BMK_benchMemAdvanced(const void* srcBuffer, size_t srcSize,
|
BMK_benchOutcome_t BMK_benchMemAdvanced(const void* srcBuffer, size_t srcSize,
|
||||||
void* dstBuffer, size_t dstCapacity,
|
void* dstBuffer, size_t dstCapacity,
|
||||||
const size_t* fileSizes, unsigned nbFiles,
|
const size_t* fileSizes, unsigned nbFiles,
|
||||||
const int cLevel, const ZSTD_compressionParameters* comprParams,
|
int cLevel, const ZSTD_compressionParameters* comprParams,
|
||||||
const void* dictBuffer, size_t dictBufferSize,
|
const void* dictBuffer, size_t dictBufferSize,
|
||||||
int displayLevel, const char* displayName,
|
int displayLevel, const char* displayName,
|
||||||
const BMK_advancedParams_t* adv);
|
const BMK_advancedParams_t* adv);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ==== Benchmarking any function, iterated on a set of blocks ==== */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t sumOfReturn; /* sum of return values */
|
unsigned long long nanoSecPerRun; /* time per iteration */
|
||||||
U64 nanoSecPerRun; /* time per iteration */
|
size_t sumOfReturn; /* sum of return values */
|
||||||
} BMK_customResult_t;
|
} BMK_runTime_t;
|
||||||
|
|
||||||
ERROR_STRUCT(BMK_customResult_t, BMK_customReturn_t);
|
VARIANT_ERROR_RESULT(BMK_runTime_t, BMK_runOutcome_t);
|
||||||
|
|
||||||
typedef size_t (*BMK_benchFn_t)(const void*, size_t, void*, size_t, void*);
|
/* check first if the return structure represents an error or a valid result */
|
||||||
typedef size_t (*BMK_initFn_t)(void*);
|
int BMK_isSuccessful_runOutcome(BMK_runOutcome_t outcome);
|
||||||
|
|
||||||
/* This function times the execution of 2 argument functions, benchFn and initFn */
|
/* extract result from variant type.
|
||||||
|
* note : this function will abort() program execution if result is not valid
|
||||||
|
* check result validity first, by using BMK_isSuccessful_runOutcome()
|
||||||
|
*/
|
||||||
|
BMK_runTime_t BMK_extract_runTime(BMK_runOutcome_t outcome);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef size_t (*BMK_benchFn_t)(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* customPayload);
|
||||||
|
typedef size_t (*BMK_initFn_t)(void* initPayload);
|
||||||
|
|
||||||
|
|
||||||
|
/* BMK_benchFunction() :
|
||||||
|
* This function times the execution of 2 argument functions, benchFn and initFn */
|
||||||
|
|
||||||
/* benchFn - (*benchFn)(srcBuffers[i], srcSizes[i], dstBuffers[i], dstCapacities[i], benchPayload)
|
/* benchFn - (*benchFn)(srcBuffers[i], srcSizes[i], dstBuffers[i], dstCapacities[i], benchPayload)
|
||||||
* is run nbLoops times
|
* is run nbLoops times
|
||||||
* initFn - (*initFn)(initPayload) is run once per benchmark at the beginning. This argument can
|
* initFn - (*initFn)(initPayload) is run once per benchmark, at the beginning.
|
||||||
* be NULL, in which case nothing is run.
|
* This argument can be NULL, in which case nothing is run.
|
||||||
* blockCount - number of blocks (size of srcBuffers, srcSizes, dstBuffers, dstCapacities)
|
* blockCount - number of blocks. Size of all array parameters : srcBuffers, srcSizes, dstBuffers, dstCapacities, blockResults
|
||||||
* srcBuffers - an array of buffers to be operated on by benchFn
|
* srcBuffers - an array of buffers to be operated on by benchFn
|
||||||
* srcSizes - an array of the sizes of above buffers
|
* srcSizes - an array of the sizes of above buffers
|
||||||
* dstBuffers - an array of buffers to be written into by benchFn
|
* dstBuffers - an array of buffers to be written into by benchFn
|
||||||
* dstCapacities - an array of the capacities of above buffers
|
* dstCapacities - an array of the capacities of above buffers
|
||||||
* blockResults - the return value of benchFn called on each block.
|
* blockResults - store the return value of benchFn for each block. Optional. Use NULL if this result is not requested.
|
||||||
* nbLoops - defines number of times benchFn is run.
|
* nbLoops - defines number of times benchFn is run.
|
||||||
* assumed array of size blockCount, will have compressed size of each block written to it.
|
* @return: a variant, which express either an error, or can generate a valid BMK_runTime_t result.
|
||||||
* return
|
* Use BMK_isSuccessful_runOutcome() to check if function was successful.
|
||||||
* .error will give a nonzero value if ZSTD_isError() is nonzero for any of the return
|
* If yes, extract the result with BMK_extract_runTime(),
|
||||||
* of the calls to initFn and benchFn, or if benchFunction errors internally
|
* it will contain :
|
||||||
* .result - if .error = 0, then .result will contain the sum of all return values of
|
* .sumOfReturn : the sum of all return values of benchFn through all of blocks
|
||||||
* benchFn on the first iteration through all of the blocks (.sumOfReturn) and also
|
* .nanoSecPerRun : time per run of benchFn + (time for initFn / nbLoops)
|
||||||
* the time per run of benchFn (.nanoSecPerRun). For the former, this
|
* .sumOfReturn is generally intended for functions which return a # of bytes written into dstBuffer,
|
||||||
* is generally intended to be used on functions which return the # of bytes written
|
* in which case, this value will be the total amount of bytes written into dstBuffer.
|
||||||
* into dstBuffer, hence this value will be the total amount of bytes written to
|
|
||||||
* dstBuffer.
|
|
||||||
*/
|
*/
|
||||||
BMK_customReturn_t BMK_benchFunction(BMK_benchFn_t benchFn, void* benchPayload,
|
BMK_runOutcome_t BMK_benchFunction(
|
||||||
|
BMK_benchFn_t benchFn, void* benchPayload,
|
||||||
BMK_initFn_t initFn, void* initPayload,
|
BMK_initFn_t initFn, void* initPayload,
|
||||||
size_t blockCount,
|
size_t blockCount,
|
||||||
const void* const * const srcBuffers, const size_t* srcSizes,
|
const void *const * srcBuffers, const size_t* srcSizes,
|
||||||
void * const * const dstBuffers, const size_t* dstCapacities, size_t* blockResults,
|
void *const * dstBuffers, const size_t* dstCapacities,
|
||||||
|
size_t* blockResults,
|
||||||
unsigned nbLoops);
|
unsigned nbLoops);
|
||||||
|
|
||||||
|
|
||||||
/* state information needed to advance computation for benchFunctionTimed */
|
|
||||||
typedef struct BMK_timeState_t BMK_timedFnState_t;
|
|
||||||
/* initializes timeState object with desired number of seconds */
|
|
||||||
BMK_timedFnState_t* BMK_createTimeState(unsigned nbSeconds);
|
|
||||||
/* resets existing timeState object */
|
|
||||||
void BMK_resetTimeState(BMK_timedFnState_t*, unsigned nbSeconds);
|
|
||||||
/* deletes timeState object */
|
|
||||||
void BMK_freeTimeState(BMK_timedFnState_t* state);
|
|
||||||
|
|
||||||
typedef struct {
|
/* ==== Benchmark any function, providing intermediate results ==== */
|
||||||
BMK_customReturn_t result;
|
|
||||||
int completed;
|
|
||||||
} BMK_customTimedReturn_t;
|
|
||||||
|
|
||||||
/*
|
/* state information tracking benchmark session */
|
||||||
* Benchmarks custom functions like BMK_benchFunction(), but runs for nbSeconds seconds rather than a fixed number of loops
|
typedef struct BMK_timedFnState_s BMK_timedFnState_t;
|
||||||
* arguments mostly the same other than BMK_benchFunction()
|
|
||||||
* Usage - benchFunctionTimed will return in approximately one second. Keep calling BMK_benchFunctionTimed() until the return's completed field = 1.
|
/* BMK_createTimedFnState() and BMK_resetTimedFnState() :
|
||||||
* to continue updating intermediate result. Intermediate return values are returned by the function.
|
* Create/Set BMK_timedFnState_t for next benchmark session,
|
||||||
|
* which shall last a minimum of total_ms milliseconds,
|
||||||
|
* producing intermediate results, paced at interval of (approximately) run_ms.
|
||||||
*/
|
*/
|
||||||
BMK_customTimedReturn_t BMK_benchFunctionTimed(BMK_timedFnState_t* cont,
|
BMK_timedFnState_t* BMK_createTimedFnState(unsigned total_ms, unsigned run_ms);
|
||||||
BMK_benchFn_t benchFn, void* benchPayload,
|
void BMK_resetTimedFnState(BMK_timedFnState_t* timedFnState, unsigned total_ms, unsigned run_ms);
|
||||||
BMK_initFn_t initFn, void* initPayload,
|
void BMK_freeTimedFnState(BMK_timedFnState_t* state);
|
||||||
size_t blockCount,
|
|
||||||
const void* const * const srcBlockBuffers, const size_t* srcBlockSizes,
|
|
||||||
void* const * const dstBlockBuffers, const size_t* dstBlockCapacities, size_t* blockResults);
|
/* Tells if duration of all benchmark runs has exceeded total_ms
|
||||||
|
*/
|
||||||
|
int BMK_isCompleted_TimedFn(const BMK_timedFnState_t* timedFnState);
|
||||||
|
|
||||||
|
|
||||||
|
/* BMK_benchTimedFn() :
|
||||||
|
* Similar to BMK_benchFunction(), most arguments being identical.
|
||||||
|
* Automatically determines `nbLoops` so that each result is regularly produced at interval of about run_ms.
|
||||||
|
* Note : minimum `nbLoops` is 1, therefore a run may last more than run_ms, and possibly even more than total_ms.
|
||||||
|
* Usage - initialize timedFnState, select benchmark duration (total_ms) and each measurement duration (run_ms)
|
||||||
|
* call BMK_benchTimedFn() repetitively, each measurement is supposed to last about run_ms
|
||||||
|
* Check if total time budget is spent or exceeded, using BMK_isCompleted_TimedFn()
|
||||||
|
*/
|
||||||
|
BMK_runOutcome_t BMK_benchTimedFn(
|
||||||
|
BMK_timedFnState_t* timedFnState,
|
||||||
|
BMK_benchFn_t benchFn, void* benchPayload,
|
||||||
|
BMK_initFn_t initFn, void* initPayload,
|
||||||
|
size_t blockCount,
|
||||||
|
const void *const * srcBlockBuffers, const size_t* srcBlockSizes,
|
||||||
|
void *const * dstBlockBuffers, const size_t* dstBlockCapacities,
|
||||||
|
size_t* blockResults);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BENCH_H_121279284357 */
|
#endif /* BENCH_H_121279284357 */
|
||||||
|
|
||||||
|
@ -901,13 +901,13 @@ int main(int argCount, const char* argv[])
|
|||||||
if (cLevelLast > ZSTD_maxCLevel()) cLevelLast = ZSTD_maxCLevel();
|
if (cLevelLast > ZSTD_maxCLevel()) cLevelLast = ZSTD_maxCLevel();
|
||||||
if (cLevelLast < cLevel) cLevelLast = cLevel;
|
if (cLevelLast < cLevel) cLevelLast = cLevel;
|
||||||
if (cLevelLast > cLevel)
|
if (cLevelLast > cLevel)
|
||||||
DISPLAYLEVEL(2, "Benchmarking levels from %d to %d\n", cLevel, cLevelLast);
|
DISPLAYLEVEL(3, "Benchmarking levels from %d to %d\n", cLevel, cLevelLast);
|
||||||
if(filenameIdx) {
|
if(filenameIdx) {
|
||||||
if(separateFiles) {
|
if(separateFiles) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for(i = 0; i < filenameIdx; i++) {
|
for(i = 0; i < filenameIdx; i++) {
|
||||||
int c;
|
int c;
|
||||||
DISPLAYLEVEL(2, "Benchmarking %s \n", filenameTable[i]);
|
DISPLAYLEVEL(3, "Benchmarking %s \n", filenameTable[i]);
|
||||||
for(c = cLevel; c <= cLevelLast; c++) {
|
for(c = cLevel; c <= cLevelLast; c++) {
|
||||||
BMK_benchFilesAdvanced(&filenameTable[i], 1, dictFileName, c, &compressionParams, g_displayLevel, &benchParams);
|
BMK_benchFilesAdvanced(&filenameTable[i], 1, dictFileName, c, &compressionParams, g_displayLevel, &benchParams);
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ zstreamtest-dll : $(ZSTDDIR)/common/xxhash.c # xxh symbols not exposed from dll
|
|||||||
zstreamtest-dll : $(ZSTREAM_LOCAL_FILES)
|
zstreamtest-dll : $(ZSTREAM_LOCAL_FILES)
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT)
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT)
|
||||||
|
|
||||||
paramgrill : DEBUGFLAGS = -DNDEBUG # turn off assert() for speed measurements
|
paramgrill : DEBUGFLAGS = # turn off assert() by default for speed measurements
|
||||||
paramgrill : $(ZSTD_FILES) $(PRGDIR)/bench.c $(PRGDIR)/datagen.c paramgrill.c
|
paramgrill : $(ZSTD_FILES) $(PRGDIR)/bench.c $(PRGDIR)/datagen.c paramgrill.c
|
||||||
$(CC) $(FLAGS) $^ -lm -o $@$(EXT)
|
$(CC) $(FLAGS) $^ -lm -o $@$(EXT)
|
||||||
|
|
||||||
|
@ -620,6 +620,8 @@ static size_t writeLiteralsBlock(U32* seed, frame_t* frame, size_t contentSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void initSeqStore(seqStore_t *seqStore) {
|
static inline void initSeqStore(seqStore_t *seqStore) {
|
||||||
|
seqStore->maxNbSeq = MAX_NB_SEQ;
|
||||||
|
seqStore->maxNbLit = ZSTD_BLOCKSIZE_MAX;
|
||||||
seqStore->sequencesStart = SEQUENCE_BUFFER;
|
seqStore->sequencesStart = SEQUENCE_BUFFER;
|
||||||
seqStore->litStart = SEQUENCE_LITERAL_BUFFER;
|
seqStore->litStart = SEQUENCE_LITERAL_BUFFER;
|
||||||
seqStore->llCode = SEQUENCE_LLCODE;
|
seqStore->llCode = SEQUENCE_LLCODE;
|
||||||
|
@ -51,6 +51,8 @@
|
|||||||
#define COMPRESSIBILITY_DEFAULT 0.50
|
#define COMPRESSIBILITY_DEFAULT 0.50
|
||||||
static const size_t g_sampleSize = 10000000;
|
static const size_t g_sampleSize = 10000000;
|
||||||
|
|
||||||
|
#define TIMELOOP_NANOSEC (1*1000000000ULL) /* 1 second */
|
||||||
|
|
||||||
|
|
||||||
/*_************************************
|
/*_************************************
|
||||||
* Macros
|
* Macros
|
||||||
@ -92,63 +94,30 @@ static size_t BMK_findMaxMem(U64 requiredMem)
|
|||||||
return (size_t) requiredMem;
|
return (size_t) requiredMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*_*******************************************************
|
|
||||||
* Argument Parsing
|
|
||||||
*********************************************************/
|
|
||||||
|
|
||||||
#define ERROR_OUT(msg) { DISPLAY("%s \n", msg); exit(1); }
|
|
||||||
|
|
||||||
static unsigned readU32FromChar(const char** stringPtr)
|
|
||||||
{
|
|
||||||
const char errorMsg[] = "error: numeric value too large";
|
|
||||||
unsigned result = 0;
|
|
||||||
while ((**stringPtr >='0') && (**stringPtr <='9')) {
|
|
||||||
unsigned const max = (((unsigned)(-1)) / 10) - 1;
|
|
||||||
if (result > max) ERROR_OUT(errorMsg);
|
|
||||||
result *= 10, result += **stringPtr - '0', (*stringPtr)++ ;
|
|
||||||
}
|
|
||||||
if ((**stringPtr=='K') || (**stringPtr=='M')) {
|
|
||||||
unsigned const maxK = ((unsigned)(-1)) >> 10;
|
|
||||||
if (result > maxK) ERROR_OUT(errorMsg);
|
|
||||||
result <<= 10;
|
|
||||||
if (**stringPtr=='M') {
|
|
||||||
if (result > maxK) ERROR_OUT(errorMsg);
|
|
||||||
result <<= 10;
|
|
||||||
}
|
|
||||||
(*stringPtr)++; /* skip `K` or `M` */
|
|
||||||
if (**stringPtr=='i') (*stringPtr)++;
|
|
||||||
if (**stringPtr=='B') (*stringPtr)++;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned longCommandWArg(const char** stringPtr, const char* longCommand)
|
|
||||||
{
|
|
||||||
size_t const comSize = strlen(longCommand);
|
|
||||||
int const result = !strncmp(*stringPtr, longCommand, comSize);
|
|
||||||
if (result) *stringPtr += comSize;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*_*******************************************************
|
/*_*******************************************************
|
||||||
* Benchmark wrappers
|
* Benchmark wrappers
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
|
||||||
|
|
||||||
static ZSTD_CCtx* g_zcc = NULL;
|
static ZSTD_CCtx* g_zcc = NULL;
|
||||||
|
|
||||||
size_t local_ZSTD_compress(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2)
|
static size_t
|
||||||
|
local_ZSTD_compress(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
ZSTD_parameters p;
|
ZSTD_parameters p;
|
||||||
ZSTD_frameParameters f = {1 /* contentSizeHeader*/, 0, 0};
|
ZSTD_frameParameters f = { 1 /* contentSizeHeader*/, 0, 0 };
|
||||||
p.fParams = f;
|
p.fParams = f;
|
||||||
p.cParams = *(ZSTD_compressionParameters*)buff2;
|
p.cParams = *(ZSTD_compressionParameters*)buff2;
|
||||||
return ZSTD_compress_advanced (g_zcc,dst, dstSize, src, srcSize, NULL ,0, p);
|
return ZSTD_compress_advanced (g_zcc, dst, dstSize, src, srcSize, NULL ,0, p);
|
||||||
//return ZSTD_compress(dst, dstSize, src, srcSize, cLevel);
|
//return ZSTD_compress(dst, dstSize, src, srcSize, cLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t g_cSize = 0;
|
static size_t g_cSize = 0;
|
||||||
size_t local_ZSTD_decompress(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2)
|
static size_t local_ZSTD_decompress(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
(void)src; (void)srcSize;
|
(void)src; (void)srcSize;
|
||||||
return ZSTD_decompress(dst, dstSize, buff2, g_cSize);
|
return ZSTD_decompress(dst, dstSize, buff2, g_cSize);
|
||||||
@ -174,7 +143,10 @@ size_t local_ZSTD_decodeSeqHeaders(const void* src, size_t srcSize, void* dst, s
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static ZSTD_CStream* g_cstream= NULL;
|
static ZSTD_CStream* g_cstream= NULL;
|
||||||
size_t local_ZSTD_compressStream(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* buff2)
|
static size_t
|
||||||
|
local_ZSTD_compressStream(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
ZSTD_outBuffer buffOut;
|
ZSTD_outBuffer buffOut;
|
||||||
ZSTD_inBuffer buffIn;
|
ZSTD_inBuffer buffIn;
|
||||||
@ -194,7 +166,10 @@ size_t local_ZSTD_compressStream(const void* src, size_t srcSize, void* dst, siz
|
|||||||
return buffOut.pos;
|
return buffOut.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t local_ZSTD_compress_generic_end(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* buff2)
|
static size_t
|
||||||
|
local_ZSTD_compress_generic_end(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
ZSTD_outBuffer buffOut;
|
ZSTD_outBuffer buffOut;
|
||||||
ZSTD_inBuffer buffIn;
|
ZSTD_inBuffer buffIn;
|
||||||
@ -209,7 +184,10 @@ static size_t local_ZSTD_compress_generic_end(const void* src, size_t srcSize, v
|
|||||||
return buffOut.pos;
|
return buffOut.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t local_ZSTD_compress_generic_continue(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* buff2)
|
static size_t
|
||||||
|
local_ZSTD_compress_generic_continue(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
ZSTD_outBuffer buffOut;
|
ZSTD_outBuffer buffOut;
|
||||||
ZSTD_inBuffer buffIn;
|
ZSTD_inBuffer buffIn;
|
||||||
@ -225,7 +203,10 @@ static size_t local_ZSTD_compress_generic_continue(const void* src, size_t srcSi
|
|||||||
return buffOut.pos;
|
return buffOut.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t local_ZSTD_compress_generic_T2_end(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* buff2)
|
static size_t
|
||||||
|
local_ZSTD_compress_generic_T2_end(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
ZSTD_outBuffer buffOut;
|
ZSTD_outBuffer buffOut;
|
||||||
ZSTD_inBuffer buffIn;
|
ZSTD_inBuffer buffIn;
|
||||||
@ -241,7 +222,10 @@ static size_t local_ZSTD_compress_generic_T2_end(const void* src, size_t srcSize
|
|||||||
return buffOut.pos;
|
return buffOut.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t local_ZSTD_compress_generic_T2_continue(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* buff2)
|
static size_t
|
||||||
|
local_ZSTD_compress_generic_T2_continue(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
ZSTD_outBuffer buffOut;
|
ZSTD_outBuffer buffOut;
|
||||||
ZSTD_inBuffer buffIn;
|
ZSTD_inBuffer buffIn;
|
||||||
@ -259,7 +243,10 @@ static size_t local_ZSTD_compress_generic_T2_continue(const void* src, size_t sr
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ZSTD_DStream* g_dstream= NULL;
|
static ZSTD_DStream* g_dstream= NULL;
|
||||||
static size_t local_ZSTD_decompressStream(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* buff2)
|
static size_t
|
||||||
|
local_ZSTD_decompressStream(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
ZSTD_outBuffer buffOut;
|
ZSTD_outBuffer buffOut;
|
||||||
ZSTD_inBuffer buffIn;
|
ZSTD_inBuffer buffIn;
|
||||||
@ -276,10 +263,12 @@ static size_t local_ZSTD_decompressStream(const void* src, size_t srcSize, void*
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ZSTD_DLL_IMPORT
|
#ifndef ZSTD_DLL_IMPORT
|
||||||
size_t local_ZSTD_compressContinue(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* buff2)
|
size_t local_ZSTD_compressContinue(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
ZSTD_parameters p;
|
ZSTD_parameters p;
|
||||||
ZSTD_frameParameters f = {1 /* contentSizeHeader*/, 0, 0};
|
ZSTD_frameParameters f = { 1 /* contentSizeHeader*/, 0, 0 };
|
||||||
p.fParams = f;
|
p.fParams = f;
|
||||||
p.cParams = *(ZSTD_compressionParameters*)buff2;
|
p.cParams = *(ZSTD_compressionParameters*)buff2;
|
||||||
ZSTD_compressBegin_advanced(g_zcc, NULL, 0, p, srcSize);
|
ZSTD_compressBegin_advanced(g_zcc, NULL, 0, p, srcSize);
|
||||||
@ -287,26 +276,38 @@ size_t local_ZSTD_compressContinue(const void* src, size_t srcSize, void* dst, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define FIRST_BLOCK_SIZE 8
|
#define FIRST_BLOCK_SIZE 8
|
||||||
size_t local_ZSTD_compressContinue_extDict(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* buff2)
|
size_t local_ZSTD_compressContinue_extDict(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
BYTE firstBlockBuf[FIRST_BLOCK_SIZE];
|
BYTE firstBlockBuf[FIRST_BLOCK_SIZE];
|
||||||
|
|
||||||
ZSTD_parameters p;
|
ZSTD_parameters p;
|
||||||
ZSTD_frameParameters f = {1 , 0, 0};
|
ZSTD_frameParameters f = { 1, 0, 0 };
|
||||||
p.fParams = f;
|
p.fParams = f;
|
||||||
p.cParams = *(ZSTD_compressionParameters*)buff2;
|
p.cParams = *(ZSTD_compressionParameters*)buff2;
|
||||||
ZSTD_compressBegin_advanced(g_zcc, NULL, 0, p, srcSize);
|
ZSTD_compressBegin_advanced(g_zcc, NULL, 0, p, srcSize);
|
||||||
memcpy(firstBlockBuf, src, FIRST_BLOCK_SIZE);
|
memcpy(firstBlockBuf, src, FIRST_BLOCK_SIZE);
|
||||||
|
|
||||||
{ size_t const compressResult = ZSTD_compressContinue(g_zcc, dst, dstCapacity, firstBlockBuf, FIRST_BLOCK_SIZE);
|
{ size_t const compressResult = ZSTD_compressContinue(g_zcc,
|
||||||
if (ZSTD_isError(compressResult)) { DISPLAY("local_ZSTD_compressContinue_extDict error : %s\n", ZSTD_getErrorName(compressResult)); return compressResult; }
|
dst, dstCapacity,
|
||||||
|
firstBlockBuf, FIRST_BLOCK_SIZE);
|
||||||
|
if (ZSTD_isError(compressResult)) {
|
||||||
|
DISPLAY("local_ZSTD_compressContinue_extDict error : %s\n",
|
||||||
|
ZSTD_getErrorName(compressResult));
|
||||||
|
return compressResult;
|
||||||
|
}
|
||||||
dst = (BYTE*)dst + compressResult;
|
dst = (BYTE*)dst + compressResult;
|
||||||
dstCapacity -= compressResult;
|
dstCapacity -= compressResult;
|
||||||
}
|
}
|
||||||
return ZSTD_compressEnd(g_zcc, dst, dstCapacity, (const BYTE*)src + FIRST_BLOCK_SIZE, srcSize - FIRST_BLOCK_SIZE);
|
return ZSTD_compressEnd(g_zcc, dst, dstCapacity,
|
||||||
|
(const BYTE*)src + FIRST_BLOCK_SIZE,
|
||||||
|
srcSize - FIRST_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t local_ZSTD_decompressContinue(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* buff2)
|
size_t local_ZSTD_decompressContinue(const void* src, size_t srcSize,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
void* buff2)
|
||||||
{
|
{
|
||||||
size_t regeneratedSize = 0;
|
size_t regeneratedSize = 0;
|
||||||
const BYTE* ip = (const BYTE*)buff2;
|
const BYTE* ip = (const BYTE*)buff2;
|
||||||
@ -314,7 +315,7 @@ size_t local_ZSTD_decompressContinue(const void* src, size_t srcSize, void* dst,
|
|||||||
BYTE* op = (BYTE*)dst;
|
BYTE* op = (BYTE*)dst;
|
||||||
size_t remainingCapacity = dstCapacity;
|
size_t remainingCapacity = dstCapacity;
|
||||||
|
|
||||||
(void)src; (void)srcSize;
|
(void)src; (void)srcSize; /* unused */
|
||||||
ZSTD_decompressBegin(g_zdc);
|
ZSTD_decompressBegin(g_zdc);
|
||||||
while (ip < iend) {
|
while (ip < iend) {
|
||||||
size_t const iSize = ZSTD_nextSrcSizeToDecompress(g_zdc);
|
size_t const iSize = ZSTD_nextSrcSizeToDecompress(g_zdc);
|
||||||
@ -333,14 +334,16 @@ size_t local_ZSTD_decompressContinue(const void* src, size_t srcSize, void* dst,
|
|||||||
/*_*******************************************************
|
/*_*******************************************************
|
||||||
* Bench functions
|
* Bench functions
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
static size_t benchMem(const void* src, size_t srcSize, U32 benchNb, int cLevel, ZSTD_compressionParameters* cparams)
|
static size_t benchMem(U32 benchNb,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
int cLevel, ZSTD_compressionParameters cparams)
|
||||||
{
|
{
|
||||||
BYTE* dstBuff;
|
|
||||||
size_t dstBuffSize = ZSTD_compressBound(srcSize);
|
size_t dstBuffSize = ZSTD_compressBound(srcSize);
|
||||||
void* buff2, *buff1;
|
BYTE* dstBuff;
|
||||||
|
void* dstBuff2;
|
||||||
|
void* buff2;
|
||||||
const char* benchName;
|
const char* benchName;
|
||||||
BMK_benchFn_t benchFunction;
|
BMK_benchFn_t benchFunction;
|
||||||
BMK_customReturn_t r;
|
|
||||||
int errorcode = 0;
|
int errorcode = 0;
|
||||||
|
|
||||||
/* Selection */
|
/* Selection */
|
||||||
@ -393,56 +396,56 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb, int cLevel,
|
|||||||
|
|
||||||
/* Allocation */
|
/* Allocation */
|
||||||
dstBuff = (BYTE*)malloc(dstBuffSize);
|
dstBuff = (BYTE*)malloc(dstBuffSize);
|
||||||
buff2 = malloc(dstBuffSize);
|
dstBuff2 = malloc(dstBuffSize);
|
||||||
if ((!dstBuff) || (!buff2)) {
|
if ((!dstBuff) || (!dstBuff2)) {
|
||||||
DISPLAY("\nError: not enough memory!\n");
|
DISPLAY("\nError: not enough memory!\n");
|
||||||
free(dstBuff); free(buff2);
|
free(dstBuff); free(dstBuff2);
|
||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
buff1 = buff2;
|
buff2 = dstBuff2;
|
||||||
if (g_zcc==NULL) g_zcc = ZSTD_createCCtx();
|
if (g_zcc==NULL) g_zcc = ZSTD_createCCtx();
|
||||||
if (g_zdc==NULL) g_zdc = ZSTD_createDCtx();
|
if (g_zdc==NULL) g_zdc = ZSTD_createDCtx();
|
||||||
if (g_cstream==NULL) g_cstream = ZSTD_createCStream();
|
if (g_cstream==NULL) g_cstream = ZSTD_createCStream();
|
||||||
if (g_dstream==NULL) g_dstream = ZSTD_createDStream();
|
if (g_dstream==NULL) g_dstream = ZSTD_createDStream();
|
||||||
|
|
||||||
/* DISPLAY("params: cLevel %d, wlog %d hlog %d clog %d slog %d slen %d tlen %d strat %d \n"
|
/* DISPLAY("params: cLevel %d, wlog %d hlog %d clog %d slog %d slen %d tlen %d strat %d \n",
|
||||||
, cLevel, cparams->windowLog, cparams->hashLog, cparams->chainLog, cparams->searchLog,
|
cLevel, cparams->windowLog, cparams->hashLog, cparams->chainLog, cparams->searchLog,
|
||||||
cparams->searchLength, cparams->targetLength, cparams->strategy);*/
|
cparams->searchLength, cparams->targetLength, cparams->strategy); */
|
||||||
|
|
||||||
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_compressionLevel, cLevel);
|
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_compressionLevel, cLevel);
|
||||||
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_windowLog, cparams->windowLog);
|
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_windowLog, cparams.windowLog);
|
||||||
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_hashLog, cparams->hashLog);
|
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_hashLog, cparams.hashLog);
|
||||||
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_chainLog, cparams->chainLog);
|
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_chainLog, cparams.chainLog);
|
||||||
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_searchLog, cparams->searchLog);
|
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_searchLog, cparams.searchLog);
|
||||||
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_minMatch, cparams->searchLength);
|
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_minMatch, cparams.searchLength);
|
||||||
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_targetLength, cparams->targetLength);
|
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_targetLength, cparams.targetLength);
|
||||||
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_compressionStrategy, cparams->strategy);
|
ZSTD_CCtx_setParameter(g_zcc, ZSTD_p_compressionStrategy, cparams.strategy);
|
||||||
|
|
||||||
|
|
||||||
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionLevel, cLevel);
|
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionLevel, cLevel);
|
||||||
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_windowLog, cparams->windowLog);
|
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_windowLog, cparams.windowLog);
|
||||||
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_hashLog, cparams->hashLog);
|
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_hashLog, cparams.hashLog);
|
||||||
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_chainLog, cparams->chainLog);
|
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_chainLog, cparams.chainLog);
|
||||||
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_searchLog, cparams->searchLog);
|
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_searchLog, cparams.searchLog);
|
||||||
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_minMatch, cparams->searchLength);
|
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_minMatch, cparams.searchLength);
|
||||||
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_targetLength, cparams->targetLength);
|
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_targetLength, cparams.targetLength);
|
||||||
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionStrategy, cparams->strategy);
|
ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionStrategy, cparams.strategy);
|
||||||
|
|
||||||
/* Preparation */
|
/* Preparation */
|
||||||
switch(benchNb)
|
switch(benchNb)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
buff2 = (void*)cparams;
|
buff2 = &cparams;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, cLevel);
|
g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, cLevel);
|
||||||
break;
|
break;
|
||||||
#ifndef ZSTD_DLL_IMPORT
|
#ifndef ZSTD_DLL_IMPORT
|
||||||
case 11:
|
case 11:
|
||||||
buff2 = (void*)cparams;
|
buff2 = &cparams;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
buff2 = (void*)cparams;
|
buff2 = &cparams;
|
||||||
break;
|
break;
|
||||||
case 13 :
|
case 13 :
|
||||||
g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, cLevel);
|
g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, cLevel);
|
||||||
@ -494,8 +497,8 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb, int cLevel,
|
|||||||
case 31:
|
case 31:
|
||||||
goto _cleanOut;
|
goto _cleanOut;
|
||||||
#endif
|
#endif
|
||||||
case 41 :
|
case 41 :
|
||||||
buff2 = (void*)cparams;
|
buff2 = &cparams;
|
||||||
break;
|
break;
|
||||||
case 42 :
|
case 42 :
|
||||||
g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, cLevel);
|
g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, cLevel);
|
||||||
@ -507,29 +510,50 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb, int cLevel,
|
|||||||
default : ;
|
default : ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* warming up dstBuff */
|
||||||
/* warming up memory */
|
|
||||||
{ size_t i; for (i=0; i<dstBuffSize; i++) dstBuff[i]=(BYTE)i; }
|
{ size_t i; for (i=0; i<dstBuffSize; i++) dstBuff[i]=(BYTE)i; }
|
||||||
|
|
||||||
|
|
||||||
/* benchmark loop */
|
/* benchmark loop */
|
||||||
{
|
{ BMK_timedFnState_t* const tfs = BMK_createTimedFnState(g_nbIterations * 1000, 1000);
|
||||||
void* dstBuffv = (void*)dstBuff;
|
BMK_runTime_t bestResult;
|
||||||
r = BMK_benchFunction(benchFunction, buff2,
|
bestResult.sumOfReturn = 0;
|
||||||
NULL, NULL, 1, &src, &srcSize,
|
bestResult.nanoSecPerRun = (unsigned long long)(-1LL);
|
||||||
&dstBuffv, &dstBuffSize, NULL, g_nbIterations);
|
assert(tfs != NULL);
|
||||||
if(r.error) {
|
for (;;) {
|
||||||
DISPLAY("ERROR %d ! ! \n", r.error);
|
void* const dstBuffv = dstBuff;
|
||||||
errorcode = r.error;
|
BMK_runOutcome_t const bOutcome =
|
||||||
goto _cleanOut;
|
BMK_benchTimedFn( tfs,
|
||||||
}
|
benchFunction, buff2,
|
||||||
|
NULL, NULL, /* initFn */
|
||||||
|
1, /* blockCount */
|
||||||
|
&src, &srcSize,
|
||||||
|
&dstBuffv, &dstBuffSize,
|
||||||
|
NULL);
|
||||||
|
|
||||||
DISPLAY("%2u#Speed: %f MB/s - Size: %f MB - %s\n", benchNb, (double)srcSize / r.result.nanoSecPerRun * 1000, (double)r.result.sumOfReturn / 1000000, benchName);
|
if (!BMK_isSuccessful_runOutcome(bOutcome)) {
|
||||||
|
DISPLAY("ERROR benchmarking function ! ! \n");
|
||||||
|
errorcode = 1;
|
||||||
|
goto _cleanOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ BMK_runTime_t const newResult = BMK_extract_runTime(bOutcome);
|
||||||
|
if (newResult.nanoSecPerRun < bestResult.nanoSecPerRun )
|
||||||
|
bestResult.nanoSecPerRun = newResult.nanoSecPerRun;
|
||||||
|
DISPLAY("\r%2u#%-29.29s:%8.1f MB/s (%8u) ",
|
||||||
|
benchNb, benchName,
|
||||||
|
(double)srcSize * TIMELOOP_NANOSEC / bestResult.nanoSecPerRun / MB_UNIT,
|
||||||
|
(unsigned)newResult.sumOfReturn );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( BMK_isCompleted_TimedFn(tfs) ) break;
|
||||||
|
}
|
||||||
|
BMK_freeTimedFnState(tfs);
|
||||||
}
|
}
|
||||||
|
DISPLAY("\n");
|
||||||
|
|
||||||
_cleanOut:
|
_cleanOut:
|
||||||
free(buff1);
|
|
||||||
free(dstBuff);
|
free(dstBuff);
|
||||||
|
free(dstBuff2);
|
||||||
ZSTD_freeCCtx(g_zcc); g_zcc=NULL;
|
ZSTD_freeCCtx(g_zcc); g_zcc=NULL;
|
||||||
ZSTD_freeDCtx(g_zdc); g_zdc=NULL;
|
ZSTD_freeDCtx(g_zdc); g_zdc=NULL;
|
||||||
ZSTD_freeCStream(g_cstream); g_cstream=NULL;
|
ZSTD_freeCStream(g_cstream); g_cstream=NULL;
|
||||||
@ -538,87 +562,138 @@ _cleanOut:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int benchSample(U32 benchNb, int cLevel, ZSTD_compressionParameters* cparams)
|
static int benchSample(U32 benchNb,
|
||||||
|
int cLevel, ZSTD_compressionParameters cparams)
|
||||||
{
|
{
|
||||||
size_t const benchedSize = g_sampleSize;
|
size_t const benchedSize = g_sampleSize;
|
||||||
const char* name = "Sample 10MiB";
|
const char* const name = "Sample 10MiB";
|
||||||
|
|
||||||
/* Allocation */
|
/* Allocation */
|
||||||
void* origBuff = malloc(benchedSize);
|
void* const origBuff = malloc(benchedSize);
|
||||||
if (!origBuff) { DISPLAY("\nError: not enough memory!\n"); return 12; }
|
if (!origBuff) { DISPLAY("\nError: not enough memory!\n"); return 12; }
|
||||||
|
|
||||||
/* Fill buffer */
|
/* Fill buffer */
|
||||||
RDG_genBuffer(origBuff, benchedSize, g_compressibility, 0.0, 0);
|
RDG_genBuffer(origBuff, benchedSize, g_compressibility, 0.0, 0);
|
||||||
|
|
||||||
/* bench */
|
/* bench */
|
||||||
DISPLAY("\r%79s\r", "");
|
DISPLAY("\r%70s\r", "");
|
||||||
DISPLAY(" %s : \n", name);
|
DISPLAY(" %s : \n", name);
|
||||||
if (benchNb)
|
if (benchNb) {
|
||||||
benchMem(origBuff, benchedSize, benchNb, cLevel, cparams);
|
benchMem(benchNb, origBuff, benchedSize, cLevel, cparams);
|
||||||
else
|
} else { /* 0 == run all tests */
|
||||||
for (benchNb=0; benchNb<100; benchNb++) benchMem(origBuff, benchedSize, benchNb, cLevel, cparams);
|
for (benchNb=0; benchNb<100; benchNb++) {
|
||||||
|
benchMem(benchNb, origBuff, benchedSize, cLevel, cparams);
|
||||||
|
} }
|
||||||
|
|
||||||
free(origBuff);
|
free(origBuff);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int benchFiles(const char** fileNamesTable, const int nbFiles, U32 benchNb, int cLevel, ZSTD_compressionParameters* cparams)
|
static int benchFiles(U32 benchNb,
|
||||||
|
const char** fileNamesTable, const int nbFiles,
|
||||||
|
int cLevel, ZSTD_compressionParameters cparams)
|
||||||
{
|
{
|
||||||
/* Loop for each file */
|
/* Loop for each file */
|
||||||
int fileIdx;
|
int fileIdx;
|
||||||
for (fileIdx=0; fileIdx<nbFiles; fileIdx++) {
|
for (fileIdx=0; fileIdx<nbFiles; fileIdx++) {
|
||||||
const char* const inFileName = fileNamesTable[fileIdx];
|
const char* const inFileName = fileNamesTable[fileIdx];
|
||||||
FILE* const inFile = fopen( inFileName, "rb" );
|
FILE* const inFile = fopen( inFileName, "rb" );
|
||||||
U64 inFileSize;
|
|
||||||
size_t benchedSize;
|
size_t benchedSize;
|
||||||
void* origBuff;
|
|
||||||
|
|
||||||
/* Check file existence */
|
/* Check file existence */
|
||||||
if (inFile==NULL) { DISPLAY( "Pb opening %s\n", inFileName); return 11; }
|
if (inFile==NULL) { DISPLAY( "Pb opening %s\n", inFileName); return 11; }
|
||||||
|
|
||||||
/* Memory allocation & restrictions */
|
/* Memory allocation & restrictions */
|
||||||
inFileSize = UTIL_getFileSize(inFileName);
|
{ U64 const inFileSize = UTIL_getFileSize(inFileName);
|
||||||
if (inFileSize == UTIL_FILESIZE_UNKNOWN) {
|
if (inFileSize == UTIL_FILESIZE_UNKNOWN) {
|
||||||
DISPLAY( "Cannot measure size of %s\n", inFileName);
|
DISPLAY( "Cannot measure size of %s\n", inFileName);
|
||||||
fclose(inFile);
|
fclose(inFile);
|
||||||
return 11;
|
return 11;
|
||||||
}
|
}
|
||||||
benchedSize = BMK_findMaxMem(inFileSize*3) / 3;
|
benchedSize = BMK_findMaxMem(inFileSize*3) / 3;
|
||||||
if ((U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize;
|
if ((U64)benchedSize > inFileSize)
|
||||||
if (benchedSize < inFileSize)
|
benchedSize = (size_t)inFileSize;
|
||||||
DISPLAY("Not enough memory for '%s' full size; testing %u MB only...\n", inFileName, (U32)(benchedSize>>20));
|
if ((U64)benchedSize < inFileSize) {
|
||||||
|
DISPLAY("Not enough memory for '%s' full size; testing %u MB only... \n",
|
||||||
/* Alloc */
|
inFileName, (U32)(benchedSize>>20));
|
||||||
origBuff = malloc(benchedSize);
|
|
||||||
if (!origBuff) { DISPLAY("\nError: not enough memory!\n"); fclose(inFile); return 12; }
|
|
||||||
|
|
||||||
/* Fill input buffer */
|
|
||||||
DISPLAY("Loading %s... \r", inFileName);
|
|
||||||
{
|
|
||||||
size_t readSize = fread(origBuff, 1, benchedSize, inFile);
|
|
||||||
fclose(inFile);
|
|
||||||
if (readSize != benchedSize) {
|
|
||||||
DISPLAY("\nError: problem reading file '%s' !! \n", inFileName);
|
|
||||||
free(origBuff);
|
|
||||||
return 13;
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/* bench */
|
/* Alloc */
|
||||||
DISPLAY("\r%79s\r", "");
|
{ void* const origBuff = malloc(benchedSize);
|
||||||
DISPLAY(" %s : \n", inFileName);
|
if (!origBuff) { DISPLAY("\nError: not enough memory!\n"); fclose(inFile); return 12; }
|
||||||
if (benchNb)
|
|
||||||
benchMem(origBuff, benchedSize, benchNb, cLevel, cparams);
|
|
||||||
else
|
|
||||||
for (benchNb=0; benchNb<100; benchNb++) benchMem(origBuff, benchedSize, benchNb, cLevel, cparams);
|
|
||||||
|
|
||||||
free(origBuff);
|
/* Fill input buffer */
|
||||||
}
|
DISPLAY("Loading %s... \r", inFileName);
|
||||||
|
{ size_t const readSize = fread(origBuff, 1, benchedSize, inFile);
|
||||||
|
fclose(inFile);
|
||||||
|
if (readSize != benchedSize) {
|
||||||
|
DISPLAY("\nError: problem reading file '%s' !! \n", inFileName);
|
||||||
|
free(origBuff);
|
||||||
|
return 13;
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* bench */
|
||||||
|
DISPLAY("\r%70s\r", ""); /* blank line */
|
||||||
|
DISPLAY(" %s : \n", inFileName);
|
||||||
|
if (benchNb) {
|
||||||
|
benchMem(benchNb, origBuff, benchedSize, cLevel, cparams);
|
||||||
|
} else {
|
||||||
|
for (benchNb=0; benchNb<100; benchNb++) {
|
||||||
|
benchMem(benchNb, origBuff, benchedSize, cLevel, cparams);
|
||||||
|
} }
|
||||||
|
|
||||||
|
free(origBuff);
|
||||||
|
} }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*_*******************************************************
|
||||||
|
* Argument Parsing
|
||||||
|
*********************************************************/
|
||||||
|
|
||||||
|
#define ERROR_OUT(msg) { DISPLAY("%s \n", msg); exit(1); }
|
||||||
|
|
||||||
|
static unsigned readU32FromChar(const char** stringPtr)
|
||||||
|
{
|
||||||
|
const char errorMsg[] = "error: numeric value too large";
|
||||||
|
unsigned result = 0;
|
||||||
|
while ((**stringPtr >='0') && (**stringPtr <='9')) {
|
||||||
|
unsigned const max = (((unsigned)(-1)) / 10) - 1;
|
||||||
|
if (result > max) ERROR_OUT(errorMsg);
|
||||||
|
result *= 10, result += **stringPtr - '0', (*stringPtr)++ ;
|
||||||
|
}
|
||||||
|
if ((**stringPtr=='K') || (**stringPtr=='M')) {
|
||||||
|
unsigned const maxK = ((unsigned)(-1)) >> 10;
|
||||||
|
if (result > maxK) ERROR_OUT(errorMsg);
|
||||||
|
result <<= 10;
|
||||||
|
if (**stringPtr=='M') {
|
||||||
|
if (result > maxK) ERROR_OUT(errorMsg);
|
||||||
|
result <<= 10;
|
||||||
|
}
|
||||||
|
(*stringPtr)++; /* skip `K` or `M` */
|
||||||
|
if (**stringPtr=='i') (*stringPtr)++;
|
||||||
|
if (**stringPtr=='B') (*stringPtr)++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned longCommandWArg(const char** stringPtr, const char* longCommand)
|
||||||
|
{
|
||||||
|
size_t const comSize = strlen(longCommand);
|
||||||
|
int const result = !strncmp(*stringPtr, longCommand, comSize);
|
||||||
|
if (result) *stringPtr += comSize;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*_*******************************************************
|
||||||
|
* Command line
|
||||||
|
*********************************************************/
|
||||||
|
|
||||||
static int usage(const char* exename)
|
static int usage(const char* exename)
|
||||||
{
|
{
|
||||||
DISPLAY( "Usage :\n");
|
DISPLAY( "Usage :\n");
|
||||||
@ -649,8 +724,8 @@ static int badusage(const char* exename)
|
|||||||
|
|
||||||
int main(int argc, const char** argv)
|
int main(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
int i, filenamesStart=0, result;
|
int argNb, filenamesStart=0, result;
|
||||||
const char* exename = argv[0];
|
const char* const exename = argv[0];
|
||||||
const char* input_filename = NULL;
|
const char* input_filename = NULL;
|
||||||
U32 benchNb = 0, main_pause = 0;
|
U32 benchNb = 0, main_pause = 0;
|
||||||
int cLevel = DEFAULT_CLEVEL;
|
int cLevel = DEFAULT_CLEVEL;
|
||||||
@ -659,8 +734,8 @@ int main(int argc, const char** argv)
|
|||||||
DISPLAY(WELCOME_MESSAGE);
|
DISPLAY(WELCOME_MESSAGE);
|
||||||
if (argc<1) return badusage(exename);
|
if (argc<1) return badusage(exename);
|
||||||
|
|
||||||
for(i=1; i<argc; i++) {
|
for (argNb=1; argNb<argc; argNb++) {
|
||||||
const char* argument = argv[i];
|
const char* argument = argv[argNb];
|
||||||
assert(argument != NULL);
|
assert(argument != NULL);
|
||||||
|
|
||||||
if (longCommandWArg(&argument, "--zstd=")) {
|
if (longCommandWArg(&argument, "--zstd=")) {
|
||||||
@ -677,12 +752,14 @@ int main(int argc, const char** argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check end of string */
|
||||||
if (argument[0] != 0) {
|
if (argument[0] != 0) {
|
||||||
DISPLAY("invalid --zstd= format\n");
|
DISPLAY("invalid --zstd= format \n");
|
||||||
return 1; // check the end of string
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (argument[0]=='-') { /* Commands (note : aggregated commands are allowed) */
|
} else if (argument[0]=='-') { /* Commands (note : aggregated commands are allowed) */
|
||||||
argument++;
|
argument++;
|
||||||
while (argument[0]!=0) {
|
while (argument[0]!=0) {
|
||||||
@ -698,35 +775,27 @@ int main(int argc, const char** argv)
|
|||||||
|
|
||||||
/* Select specific algorithm to bench */
|
/* Select specific algorithm to bench */
|
||||||
case 'b':
|
case 'b':
|
||||||
{
|
argument++;
|
||||||
argument++;
|
benchNb = readU32FromChar(&argument);
|
||||||
benchNb = readU32FromChar(&argument);
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Modify Nb Iterations */
|
/* Modify Nb Iterations */
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
argument++;
|
||||||
argument++;
|
BMK_SetNbIterations((int)readU32FromChar(&argument));
|
||||||
BMK_SetNbIterations((int)readU32FromChar(&argument));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Select compressibility of synthetic sample */
|
/* Select compressibility of synthetic sample */
|
||||||
case 'P':
|
case 'P':
|
||||||
{ argument++;
|
argument++;
|
||||||
g_compressibility = (double)readU32FromChar(&argument) / 100.;
|
g_compressibility = (double)readU32FromChar(&argument) / 100.;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
{ argument++;
|
argument++;
|
||||||
cLevel = readU32FromChar(&argument);
|
cLevel = readU32FromChar(&argument);
|
||||||
cparams = ZSTD_getCParams(cLevel, 0, 0);
|
cparams = ZSTD_getCParams(cLevel, 0, 0);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Unknown command */
|
/* Unknown command */
|
||||||
default : return badusage(exename);
|
default : return badusage(exename);
|
||||||
}
|
}
|
||||||
@ -735,15 +804,15 @@ int main(int argc, const char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* first provided filename is input */
|
/* first provided filename is input */
|
||||||
if (!input_filename) { input_filename=argument; filenamesStart=i; continue; }
|
if (!input_filename) { input_filename=argument; filenamesStart=argNb; continue; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (filenamesStart==0) /* no input file */
|
if (filenamesStart==0) /* no input file */
|
||||||
result = benchSample(benchNb, cLevel, &cparams);
|
result = benchSample(benchNb, cLevel, cparams);
|
||||||
else
|
else
|
||||||
result = benchFiles(argv+filenamesStart, argc-filenamesStart, benchNb, cLevel, &cparams);
|
result = benchFiles(benchNb, argv+filenamesStart, argc-filenamesStart, cLevel, cparams);
|
||||||
|
|
||||||
if (main_pause) { int unused; printf("press enter...\n"); unused = getchar(); (void)unused; }
|
if (main_pause) { int unused; printf("press enter...\n"); unused = getchar(); (void)unused; }
|
||||||
|
|
||||||
|
@ -1375,6 +1375,24 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
((BYTE*)CNBuffer)[i+1] = _3BytesSeqs[id][1];
|
((BYTE*)CNBuffer)[i+1] = _3BytesSeqs[id][1];
|
||||||
((BYTE*)CNBuffer)[i+2] = _3BytesSeqs[id][2];
|
((BYTE*)CNBuffer)[i+2] = _3BytesSeqs[id][2];
|
||||||
} } }
|
} } }
|
||||||
|
DISPLAYLEVEL(3, "test%3i : growing nbSeq : ", testNb++);
|
||||||
|
{ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
|
size_t const maxNbSeq = _3BYTESTESTLENGTH / 3;
|
||||||
|
size_t const bound = ZSTD_compressBound(_3BYTESTESTLENGTH);
|
||||||
|
size_t nbSeq = 1;
|
||||||
|
while (nbSeq <= maxNbSeq) {
|
||||||
|
CHECK(ZSTD_compressCCtx(cctx, compressedBuffer, bound, CNBuffer, nbSeq * 3, 19));
|
||||||
|
/* Check every sequence for the first 100, then skip more rapidly. */
|
||||||
|
if (nbSeq < 100) {
|
||||||
|
++nbSeq;
|
||||||
|
} else {
|
||||||
|
nbSeq += (nbSeq >> 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ZSTD_freeCCtx(cctx);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(3, "test%3i : compress lots 3-bytes sequences : ", testNb++);
|
DISPLAYLEVEL(3, "test%3i : compress lots 3-bytes sequences : ", testNb++);
|
||||||
{ CHECK_V(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(_3BYTESTESTLENGTH),
|
{ CHECK_V(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(_3BYTESTESTLENGTH),
|
||||||
CNBuffer, _3BYTESTESTLENGTH, 19) );
|
CNBuffer, _3BYTESTESTLENGTH, 19) );
|
||||||
@ -1386,8 +1404,26 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
if (r != _3BYTESTESTLENGTH) goto _output_error; }
|
if (r != _3BYTESTESTLENGTH) goto _output_error; }
|
||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(3, "test%3i : incompressible data and ill suited dictionary : ", testNb++);
|
|
||||||
|
DISPLAYLEVEL(3, "test%3i : growing literals buffer : ", testNb++);
|
||||||
RDG_genBuffer(CNBuffer, CNBuffSize, 0.0, 0.1, seed);
|
RDG_genBuffer(CNBuffer, CNBuffSize, 0.0, 0.1, seed);
|
||||||
|
{ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
|
size_t const bound = ZSTD_compressBound(CNBuffSize);
|
||||||
|
size_t size = 1;
|
||||||
|
while (size <= CNBuffSize) {
|
||||||
|
CHECK(ZSTD_compressCCtx(cctx, compressedBuffer, bound, CNBuffer, size, 3));
|
||||||
|
/* Check every size for the first 100, then skip more rapidly. */
|
||||||
|
if (size < 100) {
|
||||||
|
++size;
|
||||||
|
} else {
|
||||||
|
size += (size >> 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ZSTD_freeCCtx(cctx);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3i : incompressible data and ill suited dictionary : ", testNb++);
|
||||||
{ /* Train a dictionary on low characters */
|
{ /* Train a dictionary on low characters */
|
||||||
size_t dictSize = 16 KB;
|
size_t dictSize = 16 KB;
|
||||||
void* const dictBuffer = malloc(dictSize);
|
void* const dictBuffer = malloc(dictSize);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1020,6 +1020,59 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
}
|
}
|
||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3i : dictionary + uncompressible block + reusing tables checks offset table validity: ", testNb++);
|
||||||
|
{ ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(
|
||||||
|
dictionary.start, dictionary.filled,
|
||||||
|
ZSTD_dlm_byRef, ZSTD_dct_fullDict,
|
||||||
|
ZSTD_getCParams(3, 0, dictionary.filled),
|
||||||
|
ZSTD_defaultCMem);
|
||||||
|
const size_t inbufsize = 2 * 128 * 1024; /* 2 blocks */
|
||||||
|
const size_t outbufsize = ZSTD_compressBound(inbufsize);
|
||||||
|
size_t inbufpos = 0;
|
||||||
|
size_t cursegmentlen;
|
||||||
|
BYTE *inbuf = (BYTE *)malloc(inbufsize);
|
||||||
|
BYTE *outbuf = (BYTE *)malloc(outbufsize);
|
||||||
|
BYTE *checkbuf = (BYTE *)malloc(inbufsize);
|
||||||
|
size_t ret;
|
||||||
|
|
||||||
|
CHECK(cdict == NULL, "failed to alloc cdict");
|
||||||
|
CHECK(inbuf == NULL, "failed to alloc input buffer");
|
||||||
|
|
||||||
|
/* first block is uncompressible */
|
||||||
|
cursegmentlen = 128 * 1024;
|
||||||
|
RDG_genBuffer(inbuf + inbufpos, cursegmentlen, 0., 0., seed);
|
||||||
|
inbufpos += cursegmentlen;
|
||||||
|
|
||||||
|
/* second block is compressible */
|
||||||
|
cursegmentlen = 128 * 1024 - 256;
|
||||||
|
RDG_genBuffer(inbuf + inbufpos, cursegmentlen, 0.05, 0., seed);
|
||||||
|
inbufpos += cursegmentlen;
|
||||||
|
|
||||||
|
/* and includes a very long backref */
|
||||||
|
cursegmentlen = 128;
|
||||||
|
memcpy(inbuf + inbufpos, dictionary.start + 256, cursegmentlen);
|
||||||
|
inbufpos += cursegmentlen;
|
||||||
|
|
||||||
|
/* and includes a very long backref */
|
||||||
|
cursegmentlen = 128;
|
||||||
|
memcpy(inbuf + inbufpos, dictionary.start + 128, cursegmentlen);
|
||||||
|
inbufpos += cursegmentlen;
|
||||||
|
|
||||||
|
ret = ZSTD_compress_usingCDict(zc, outbuf, outbufsize, inbuf, inbufpos, cdict);
|
||||||
|
CHECK_Z(ret);
|
||||||
|
|
||||||
|
ret = ZSTD_decompress_usingDict(zd, checkbuf, inbufsize, outbuf, ret, dictionary.start, dictionary.filled);
|
||||||
|
CHECK_Z(ret);
|
||||||
|
|
||||||
|
CHECK(memcmp(inbuf, checkbuf, inbufpos), "start and finish buffers don't match");
|
||||||
|
|
||||||
|
ZSTD_freeCDict(cdict);
|
||||||
|
free(inbuf);
|
||||||
|
free(outbuf);
|
||||||
|
free(checkbuf);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
FUZ_freeDictionary(dictionary);
|
FUZ_freeDictionary(dictionary);
|
||||||
ZSTD_freeCStream(zc);
|
ZSTD_freeCStream(zc);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user