diff options
author | Yann Collet <Cyan4973@users.noreply.github.com> | 2022-09-16 05:37:40 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-16 05:37:40 (GMT) |
commit | e84f375421c131a61d096cc5649b05119b87a7a1 (patch) | |
tree | 232e2dea421437d6f3546770a3e3524dc4cac2fd | |
parent | c619263b1719b8fe7f5994e2ca39dff1a3fa4ebd (diff) | |
parent | 251e04a9c17a0d9422727473f28e215fc2c6ae20 (diff) | |
download | lz4-e84f375421c131a61d096cc5649b05119b87a7a1.zip lz4-e84f375421c131a61d096cc5649b05119b87a7a1.tar.gz lz4-e84f375421c131a61d096cc5649b05119b87a7a1.tar.bz2 |
Merge pull request #1168 from lz4/benchD
fix benchmark more using Dictionary
-rw-r--r-- | lib/lz4.c | 29 | ||||
-rw-r--r-- | lib/lz4hc.c | 13 | ||||
-rw-r--r-- | programs/bench.c | 60 | ||||
-rw-r--r-- | tests/Makefile | 1 |
4 files changed, 72 insertions, 31 deletions
@@ -279,7 +279,7 @@ static const int LZ4_minLength = (MFLIMIT+1); static int g_debuglog_enable = 1; # define DEBUGLOG(l, ...) { \ if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \ - fprintf(stderr, __FILE__ ": "); \ + fprintf(stderr, __FILE__ " %i: ", __LINE__); \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, " \n"); \ } } @@ -1991,6 +1991,7 @@ LZ4_decompress_generic( } /* Fast loop : decode sequences as long as output < oend-FASTLOOP_SAFE_DISTANCE */ + DEBUGLOG(6, "using fast decode loop"); while (1) { /* Main fastloop assertion: We can always wildcopy FASTLOOP_SAFE_DISTANCE */ assert(oend - op >= FASTLOOP_SAFE_DISTANCE); @@ -2001,7 +2002,10 @@ LZ4_decompress_generic( /* decode literal length */ if (length == RUN_MASK) { size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1); - if (addl == rvl_error) { goto _output_error; } + if (addl == rvl_error) { + DEBUGLOG(6, "error reading long literal length"); + goto _output_error; + } length += addl; if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */ if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */ @@ -2024,6 +2028,7 @@ LZ4_decompress_generic( /* get offset */ offset = LZ4_readLE16(ip); ip+=2; + DEBUGLOG(6, " offset = %zu", offset); match = op - offset; assert(match <= op); /* overflow check */ @@ -2032,11 +2037,17 @@ LZ4_decompress_generic( if (length == ML_MASK) { size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); - if (addl == rvl_error) { goto _output_error; } + if (addl == rvl_error) { + DEBUGLOG(6, "error reading long match length"); + goto _output_error; + } length += addl; length += MINMATCH; if (unlikely((uptrval)(op)+length<(uptrval)op)) { goto _output_error; } /* overflow detection */ - if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) { goto _output_error; } /* Error : offset outside buffers */ + if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) { + DEBUGLOG(6, "Error : offset outside buffers"); + goto _output_error; + } if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { goto safe_match_copy; } @@ -2060,7 +2071,10 @@ LZ4_decompress_generic( continue; } } } - if (checkOffset && (unlikely(match + dictSize < lowPrefix))) { goto _output_error; } /* Error : offset outside buffers */ + if ( checkOffset && (unlikely(match + dictSize < lowPrefix)) ) { + DEBUGLOG(6, "Error : pos=%zi, offset=%zi => outside buffers", op-lowPrefix, op-match); + goto _output_error; + } /* match starting within external dictionary */ if ((dict==usingExtDict) && (match < lowPrefix)) { assert(dictEnd != NULL); @@ -2069,7 +2083,8 @@ LZ4_decompress_generic( DEBUGLOG(7, "partialDecoding: dictionary match, close to dstEnd"); length = MIN(length, (size_t)(oend-op)); } else { - goto _output_error; /* end-of-block condition violated */ + DEBUGLOG(6, "end-of-block condition violated") + goto _output_error; } } if (length <= (size_t)(lowPrefix-match)) { @@ -2109,6 +2124,7 @@ LZ4_decompress_generic( #endif /* Main Loop : decode remaining sequences where output < FASTLOOP_SAFE_DISTANCE */ + DEBUGLOG(6, "using safe decode loop"); while (1) { assert(ip < iend); token = *ip++; @@ -2416,6 +2432,7 @@ int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const void* dictStart, size_t dictSize) { + DEBUGLOG(5, "LZ4_decompress_safe_forceExtDict"); return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, decode_full_block, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); diff --git a/lib/lz4hc.c b/lib/lz4hc.c index e83246b..fa3e014 100644 --- a/lib/lz4hc.c +++ b/lib/lz4hc.c @@ -102,6 +102,7 @@ static void LZ4HC_init_internal (LZ4HC_CCtx_internal* hc4, const BYTE* start) { size_t const bufferSize = (size_t)(hc4->end - hc4->prefixStart); size_t newStartingOffset = bufferSize + hc4->dictLimit; + DEBUGLOG(5, "LZ4HC_init_internal"); assert(newStartingOffset >= bufferSize); /* check overflow */ if (newStartingOffset > 1 GB) { LZ4HC_clearTables(hc4); @@ -422,6 +423,7 @@ LZ4HC_InsertAndGetWiderMatch ( U32 dictMatchIndex = dictCtx->hashTable[LZ4HC_hashPtr(ip)]; assert(dictEndOffset <= 1 GB); matchIndex = dictMatchIndex + lowestMatchIndex - (U32)dictEndOffset; + if (dictMatchIndex>0) DEBUGLOG(7, "dictEndOffset = %zu, dictMatchIndex = %u => relative matchIndex = %i", dictEndOffset, dictMatchIndex, (int)dictMatchIndex - (int)dictEndOffset); while (ipIndex - matchIndex <= LZ4_DISTANCE_MAX && nbAttempts--) { const BYTE* const matchPtr = dictCtx->prefixStart - dictCtx->dictLimit + dictMatchIndex; @@ -437,6 +439,7 @@ LZ4HC_InsertAndGetWiderMatch ( longest = mlt; *matchpos = prefixPtr - prefixIdx + matchIndex + back; *startpos = ip + back; + DEBUGLOG(8, "found match of length %i at vPos=%i", longest, (int)matchIndex - (int)prefixIdx + back); } } { U32 const nextOffset = DELTANEXTU16(dictCtx->chainTable, dictMatchIndex); @@ -456,6 +459,7 @@ LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal* const hc4, /* Index table wi const dictCtx_directive dict) { const BYTE* uselessPtr = ip; + DEBUGLOG(7, "LZ4HC_InsertAndFindBestMatch"); /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos), * but this won't be the case here, as we define iLowLimit==ip, * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */ @@ -585,6 +589,7 @@ LZ4_FORCE_INLINE int LZ4HC_compress_hashChain ( const BYTE* ref3 = NULL; /* init */ + DEBUGLOG(5, "LZ4HC_compress_hashChain (dict?=>%i)", dict); *srcSizePtr = 0; if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */ if (inputSize < LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */ @@ -831,8 +836,8 @@ LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal ( { lz4opt,16384,LZ4_OPT_NUM }, /* 12==LZ4HC_CLEVEL_MAX */ }; - DEBUGLOG(4, "LZ4HC_compress_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)", - ctx, src, *srcSizePtr, limit); + DEBUGLOG(5, "LZ4HC_compress_generic_internal(src=%p, srcSize=%d)", + src, *srcSizePtr); if (limit == fillOutput && dstCapacity < 1) return 0; /* Impossible to store anything */ if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size (too large or negative) */ @@ -966,6 +971,7 @@ int LZ4_compress_HC(const char* src, char* dst, int srcSize, int dstCapacity, in LZ4_streamHC_t state; LZ4_streamHC_t* const statePtr = &state; #endif + DEBUGLOG(5, "LZ4_compress_HC") cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel); #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 FREEMEM(statePtr); @@ -1034,7 +1040,7 @@ void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) void LZ4_resetStreamHC_fast (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) { LZ4HC_CCtx_internal* const s = &LZ4_streamHCPtr->internal_donotuse; - DEBUGLOG(4, "LZ4_resetStreamHC_fast(%p, %d)", LZ4_streamHCPtr, compressionLevel); + DEBUGLOG(5, "LZ4_resetStreamHC_fast(%p, %d)", LZ4_streamHCPtr, compressionLevel); if (s->dirty) { LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr)); } else { @@ -1150,6 +1156,7 @@ LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr, int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* src, char* dst, int srcSize, int dstCapacity) { + DEBUGLOG(5, "LZ4_compress_HC_continue"); if (dstCapacity < LZ4_compressBound(srcSize)) return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, limitedOutput); else diff --git a/programs/bench.c b/programs/bench.c index 4d35ef9..2d9961d 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -242,6 +242,7 @@ LZ4_compressBlockStream(const struct compressionParameters* pThis, int srcSize, int dstSize) { int const acceleration = (pThis->cLevel < 0) ? -pThis->cLevel + 1 : 1; + LZ4_compressResetStream(pThis); return LZ4_compress_fast_continue(pThis->LZ4_stream, src, dst, srcSize, dstSize, acceleration); } @@ -250,6 +251,7 @@ LZ4_compressBlockStreamHC(const struct compressionParameters* pThis, const char* src, char* dst, int srcSize, int dstSize) { + LZ4_compressResetStreamHC(pThis); return LZ4_compress_HC_continue(pThis->LZ4_streamHC, src, dst, srcSize, dstSize); } @@ -367,6 +369,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, size_t const maxInSize = (size_t)LZ4_MAX_INPUT_SIZE / decMultiplier; size_t const maxDecSize = srcSize < maxInSize ? srcSize * decMultiplier : LZ4_MAX_INPUT_SIZE; void* const resultBuffer = malloc(maxDecSize); + int benchError = 0; U32 nbBlocks; struct compressionParameters compP; @@ -463,7 +466,10 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, &compP, blockTable[blockNb].srcPtr, blockTable[blockNb].cPtr, (int)blockTable[blockNb].srcSize, (int)blockTable[blockNb].cRoom); - if (LZ4_isError(rSize)) END_PROCESS(1, "LZ4 compression failed"); + if (LZ4_isError(rSize)) { + DISPLAY("LZ4 compression failed on block %u", blockNb); + benchError =1 ; + } blockTable[blockNb].cSize = rSize; } } { U64 const clockSpan = UTIL_clockSpanNano(clockStart); @@ -522,7 +528,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, decString, blockNb, (unsigned)blockTable[blockNb].srcSize); if (g_decodeOnly) DISPLAY("Is input using LZ4 Frame format ? \n"); - END_PROCESS(2, "error during decoding"); + benchError = 1; break; } blockTable[blockNb].resSize = (size_t)regenSize; @@ -560,6 +566,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, if (crcOrig!=crcCheck) { size_t u; DISPLAY("\n!!! WARNING !!! %17s : Invalid Checksum : %x != %x \n", displayName, (unsigned)crcOrig, (unsigned)crcCheck); + benchError = 1; for (u=0; u<srcSize; u++) { if (((const BYTE*)srcBuffer)[u] != ((const BYTE*)resultBuffer)[u]) { U32 segNb, bNb, pos; @@ -598,7 +605,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, free(blockTable); free(compressedBuffer); free(resultBuffer); - return 0; + return benchError; } @@ -626,13 +633,13 @@ static size_t BMK_findMaxMem(U64 requiredMem) } -static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, +static int BMK_benchCLevel(void* srcBuffer, size_t benchedSize, const char* displayName, int cLevel, int cLevelLast, const size_t* fileSizes, unsigned nbFiles, const char* dictBuf, int dictSize) { int l; - + int benchError = 0; const char* pch = strrchr(displayName, '\\'); /* Windows */ if (!pch) pch = strrchr(displayName, '/'); /* Linux */ if (pch) displayName = pch+1; @@ -645,11 +652,13 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, if (cLevelLast < cLevel) cLevelLast = cLevel; for (l=cLevel; l <= cLevelLast; l++) { - BMK_benchMem(srcBuffer, benchedSize, - displayName, l, - fileSizes, nbFiles, - dictBuf, dictSize); + benchError |= BMK_benchMem( + srcBuffer, benchedSize, + displayName, l, + fileSizes, nbFiles, + dictBuf, dictSize); } + return benchError; } @@ -688,12 +697,13 @@ static void BMK_loadFiles(void* buffer, size_t bufferSize, if (totalSize == 0) END_PROCESS(12, "no data to bench"); } -static void BMK_benchFileTable(const char** fileNamesTable, unsigned nbFiles, - int cLevel, int cLevelLast, - const char* dictBuf, int dictSize) +static int BMK_benchFileTable(const char** fileNamesTable, unsigned nbFiles, + int cLevel, int cLevelLast, + const char* dictBuf, int dictSize) { void* srcBuffer; size_t benchedSize; + int benchError = 0; size_t* fileSizes = (size_t*)malloc(nbFiles * sizeof(size_t)); U64 const totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles); char mfName[20] = {0}; @@ -720,7 +730,7 @@ static void BMK_benchFileTable(const char** fileNamesTable, unsigned nbFiles, /* Bench */ snprintf (mfName, sizeof(mfName), " %u files", nbFiles); { const char* displayName = (nbFiles > 1) ? mfName : fileNamesTable[0]; - BMK_benchCLevel(srcBuffer, benchedSize, + benchError = BMK_benchCLevel(srcBuffer, benchedSize, displayName, cLevel, cLevelLast, fileSizes, nbFiles, dictBuf, dictSize); @@ -729,12 +739,14 @@ static void BMK_benchFileTable(const char** fileNamesTable, unsigned nbFiles, /* clean up */ free(srcBuffer); free(fileSizes); + return benchError; } -static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility, - const char* dictBuf, int dictSize) +static int BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility, + const char* dictBuf, int dictSize) { + int benchError = 0; char name[20] = {0}; size_t benchedSize = 10000000; void* const srcBuffer = malloc(benchedSize); @@ -747,10 +759,12 @@ static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility /* Bench */ snprintf (name, sizeof(name), "Synthetic %2u%%", (unsigned)(compressibility*100)); - BMK_benchCLevel(srcBuffer, benchedSize, name, cLevel, cLevelLast, &benchedSize, 1, dictBuf, dictSize); + benchError = BMK_benchCLevel(srcBuffer, benchedSize, name, cLevel, cLevelLast, &benchedSize, 1, dictBuf, dictSize); /* clean up */ free(srcBuffer); + + return benchError; } @@ -759,15 +773,16 @@ BMK_benchFilesSeparately(const char** fileNamesTable, unsigned nbFiles, int cLevel, int cLevelLast, const char* dictBuf, int dictSize) { + int benchError = 0; unsigned fileNb; if (cLevel > LZ4HC_CLEVEL_MAX) cLevel = LZ4HC_CLEVEL_MAX; if (cLevelLast > LZ4HC_CLEVEL_MAX) cLevelLast = LZ4HC_CLEVEL_MAX; if (cLevelLast < cLevel) cLevelLast = cLevel; for (fileNb=0; fileNb<nbFiles; fileNb++) - BMK_benchFileTable(fileNamesTable+fileNb, 1, cLevel, cLevelLast, dictBuf, dictSize); + benchError |= BMK_benchFileTable(fileNamesTable+fileNb, 1, cLevel, cLevelLast, dictBuf, dictSize); - return 0; + return benchError; } @@ -775,6 +790,7 @@ int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, int cLevel, int cLevelLast, const char* dictFileName) { + int benchError = 0; double const compressibility = (double)g_compressibilityDefault / 100; char* dictBuf = NULL; size_t dictSize = 0; @@ -824,14 +840,14 @@ int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, } if (nbFiles == 0) - BMK_syntheticTest(cLevel, cLevelLast, compressibility, dictBuf, (int)dictSize); + benchError = BMK_syntheticTest(cLevel, cLevelLast, compressibility, dictBuf, (int)dictSize); else { if (g_benchSeparately) - BMK_benchFilesSeparately(fileNamesTable, nbFiles, cLevel, cLevelLast, dictBuf, (int)dictSize); + benchError = BMK_benchFilesSeparately(fileNamesTable, nbFiles, cLevel, cLevelLast, dictBuf, (int)dictSize); else - BMK_benchFileTable(fileNamesTable, nbFiles, cLevel, cLevelLast, dictBuf, (int)dictSize); + benchError = BMK_benchFileTable(fileNamesTable, nbFiles, cLevel, cLevelLast, dictBuf, (int)dictSize); } free(dictBuf); - return 0; + return benchError; } diff --git a/tests/Makefile b/tests/Makefile index 62e364a..85bf495 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -452,6 +452,7 @@ test-lz4-dict: lz4 datagen < $(FPREFIX)-sample-32k $(LZ4) -D $(FPREFIX)-sample-0 | $(LZ4) -dD $(FPREFIX)-sample-0 | diff - $(FPREFIX)-sample-32k < $(FPREFIX)-sample-0 $(LZ4) -D $(FPREFIX)-sample-0 | $(LZ4) -dD $(FPREFIX)-sample-0 | diff - $(FPREFIX)-sample-0 + $(LZ4) -bi0 -D $(FPREFIX) $(FPREFIX)-sample-32k $(FPREFIX)-sample-32k @echo "\n ---- test lz4 dictionary loading ----" $(DATAGEN) -g128KB > $(FPREFIX)-data-128KB |