Merge pull request #1034 from facebook/longOffsetMode
Dynamic selection of long offset mode
This commit is contained in:
@@ -94,7 +94,7 @@ typedef struct {
|
|||||||
U32 baseValue;
|
U32 baseValue;
|
||||||
} ZSTD_seqSymbol;
|
} ZSTD_seqSymbol;
|
||||||
|
|
||||||
#define SEQSYMBOL_TABLE_SIZE(log) (1 + (1<<log))
|
#define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log)))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)];
|
ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)];
|
||||||
@@ -887,7 +887,6 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb
|
|||||||
case set_repeat:
|
case set_repeat:
|
||||||
if (!flagRepeatTable) return ERROR(corruption_detected);
|
if (!flagRepeatTable) return ERROR(corruption_detected);
|
||||||
return 0;
|
return 0;
|
||||||
default : /* impossible */
|
|
||||||
case set_compressed :
|
case set_compressed :
|
||||||
{ U32 tableLog;
|
{ U32 tableLog;
|
||||||
S16 norm[MaxSeq+1];
|
S16 norm[MaxSeq+1];
|
||||||
@@ -897,7 +896,11 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb
|
|||||||
ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog);
|
ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog);
|
||||||
*DTablePtr = DTableSpace;
|
*DTablePtr = DTableSpace;
|
||||||
return headerSize;
|
return headerSize;
|
||||||
} }
|
}
|
||||||
|
default : /* impossible */
|
||||||
|
assert(0);
|
||||||
|
return ERROR(GENERIC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const U32 LL_base[MaxLL+1] = {
|
static const U32 LL_base[MaxLL+1] = {
|
||||||
@@ -1245,33 +1248,63 @@ typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef size_t (*ZSTD_decompressSequences_t)(
|
typedef size_t (*ZSTD_decompressSequences_t)(
|
||||||
ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart,
|
ZSTD_DCtx *dctx, void *dst, size_t maxDstSize,
|
||||||
size_t seqSize, const ZSTD_longOffset_e isLongOffset);
|
const void *seqStart, size_t seqSize, int nbSeq,
|
||||||
|
const ZSTD_longOffset_e isLongOffset);
|
||||||
|
|
||||||
static size_t ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
|
static size_t ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
|
||||||
const void* seqStart, size_t seqSize,
|
const void* seqStart, size_t seqSize, int nbSeq,
|
||||||
const ZSTD_longOffset_e isLongOffset)
|
const ZSTD_longOffset_e isLongOffset)
|
||||||
{
|
{
|
||||||
|
DEBUGLOG(5, "ZSTD_decompressSequences");
|
||||||
#if DYNAMIC_BMI2
|
#if DYNAMIC_BMI2
|
||||||
if (dctx->bmi2) {
|
if (dctx->bmi2) {
|
||||||
return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, isLongOffset);
|
return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, isLongOffset);
|
return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
|
static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
|
||||||
const void* seqStart, size_t seqSize,
|
void* dst, size_t maxDstSize,
|
||||||
|
const void* seqStart, size_t seqSize, int nbSeq,
|
||||||
const ZSTD_longOffset_e isLongOffset)
|
const ZSTD_longOffset_e isLongOffset)
|
||||||
{
|
{
|
||||||
|
DEBUGLOG(5, "ZSTD_decompressSequencesLong");
|
||||||
#if DYNAMIC_BMI2
|
#if DYNAMIC_BMI2
|
||||||
if (dctx->bmi2) {
|
if (dctx->bmi2) {
|
||||||
return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, isLongOffset);
|
return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, isLongOffset);
|
return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ZSTD_getLongOffsetsShare() :
|
||||||
|
* condition : offTable must be valid
|
||||||
|
* @return : "share" of long offsets (arbitrarily defined as > (1<<23))
|
||||||
|
* compared to maximum possible of (1<<OffFSELog) */
|
||||||
|
static unsigned
|
||||||
|
ZSTD_getLongOffsetsShare(const ZSTD_seqSymbol* offTable)
|
||||||
|
{
|
||||||
|
const void* ptr = offTable;
|
||||||
|
U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog;
|
||||||
|
const ZSTD_seqSymbol* table = offTable + 1;
|
||||||
|
U32 const max = 1 << tableLog;
|
||||||
|
U32 u, total = 0;
|
||||||
|
DEBUGLOG(5, "ZSTD_getLongOffsetsShare: (tableLog=%u)", tableLog);
|
||||||
|
|
||||||
|
assert(max <= (1 << OffFSELog)); /* max not too large */
|
||||||
|
for (u=0; u<max; u++) {
|
||||||
|
if (table[u].nbAdditionalBits > 22) total += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(tableLog <= OffFSELog);
|
||||||
|
total <<= (OffFSELog - tableLog); /* scale to OffFSELog */
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize, const int frame)
|
const void* src, size_t srcSize, const int frame)
|
||||||
@@ -1295,12 +1328,23 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|||||||
srcSize -= litCSize;
|
srcSize -= litCSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( frame /* windowSize exists */
|
/* Build Decoding Tables */
|
||||||
&& (dctx->fParams.windowSize > (1<<24))
|
{ int nbSeq;
|
||||||
&& MEM_64bits() /* x86 benefits less from long mode than x64 */ )
|
size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize);
|
||||||
return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
|
if (ZSTD_isError(seqHSize)) return seqHSize;
|
||||||
|
ip += seqHSize;
|
||||||
|
srcSize -= seqHSize;
|
||||||
|
|
||||||
return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
|
if ( (!frame || dctx->fParams.windowSize > (1<<24))
|
||||||
|
&& (nbSeq>0) ) { /* could probably use a larger nbSeq limit */
|
||||||
|
U32 const shareLongOffsets = ZSTD_getLongOffsetsShare(dctx->OFTptr);
|
||||||
|
U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */
|
||||||
|
if (shareLongOffsets >= minShare)
|
||||||
|
return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ static TARGET
|
|||||||
size_t FUNCTION(ZSTD_decompressSequences)(
|
size_t FUNCTION(ZSTD_decompressSequences)(
|
||||||
ZSTD_DCtx* dctx,
|
ZSTD_DCtx* dctx,
|
||||||
void* dst, size_t maxDstSize,
|
void* dst, size_t maxDstSize,
|
||||||
const void* seqStart, size_t seqSize,
|
const void* seqStart, size_t seqSize, int nbSeq,
|
||||||
const ZSTD_longOffset_e isLongOffset)
|
const ZSTD_longOffset_e isLongOffset)
|
||||||
{
|
{
|
||||||
const BYTE* ip = (const BYTE*)seqStart;
|
const BYTE* ip = (const BYTE*)seqStart;
|
||||||
@@ -222,17 +222,8 @@ size_t FUNCTION(ZSTD_decompressSequences)(
|
|||||||
const BYTE* const base = (const BYTE*) (dctx->base);
|
const BYTE* const base = (const BYTE*) (dctx->base);
|
||||||
const BYTE* const vBase = (const BYTE*) (dctx->vBase);
|
const BYTE* const vBase = (const BYTE*) (dctx->vBase);
|
||||||
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
||||||
int nbSeq;
|
|
||||||
DEBUGLOG(5, "ZSTD_decompressSequences");
|
DEBUGLOG(5, "ZSTD_decompressSequences");
|
||||||
|
|
||||||
/* Build Decoding Tables */
|
|
||||||
{ size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
|
|
||||||
DEBUGLOG(5, "ZSTD_decodeSeqHeaders: size=%u, nbSeq=%i",
|
|
||||||
(U32)seqHSize, nbSeq);
|
|
||||||
if (ZSTD_isError(seqHSize)) return seqHSize;
|
|
||||||
ip += seqHSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Regen sequences */
|
/* Regen sequences */
|
||||||
if (nbSeq) {
|
if (nbSeq) {
|
||||||
seqState_t seqState;
|
seqState_t seqState;
|
||||||
@@ -273,7 +264,7 @@ static TARGET
|
|||||||
size_t FUNCTION(ZSTD_decompressSequencesLong)(
|
size_t FUNCTION(ZSTD_decompressSequencesLong)(
|
||||||
ZSTD_DCtx* dctx,
|
ZSTD_DCtx* dctx,
|
||||||
void* dst, size_t maxDstSize,
|
void* dst, size_t maxDstSize,
|
||||||
const void* seqStart, size_t seqSize,
|
const void* seqStart, size_t seqSize, int nbSeq,
|
||||||
const ZSTD_longOffset_e isLongOffset)
|
const ZSTD_longOffset_e isLongOffset)
|
||||||
{
|
{
|
||||||
const BYTE* ip = (const BYTE*)seqStart;
|
const BYTE* ip = (const BYTE*)seqStart;
|
||||||
@@ -286,13 +277,6 @@ size_t FUNCTION(ZSTD_decompressSequencesLong)(
|
|||||||
const BYTE* const prefixStart = (const BYTE*) (dctx->base);
|
const BYTE* const prefixStart = (const BYTE*) (dctx->base);
|
||||||
const BYTE* const dictStart = (const BYTE*) (dctx->vBase);
|
const BYTE* const dictStart = (const BYTE*) (dctx->vBase);
|
||||||
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
||||||
int nbSeq;
|
|
||||||
|
|
||||||
/* Build Decoding Tables */
|
|
||||||
{ size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
|
|
||||||
if (ZSTD_isError(seqHSize)) return seqHSize;
|
|
||||||
ip += seqHSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Regen sequences */
|
/* Regen sequences */
|
||||||
if (nbSeq) {
|
if (nbSeq) {
|
||||||
|
|||||||
+2
-2
@@ -475,8 +475,8 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
} /* for (testNb = 1; testNb <= (g_nbSeconds + !g_nbSeconds); testNb++) */
|
} /* for (testNb = 1; testNb <= (g_nbSeconds + !g_nbSeconds); testNb++) */
|
||||||
|
|
||||||
if (g_displayLevel == 1) { /* hidden display mode -q, used by python speed benchmark */
|
if (g_displayLevel == 1) { /* hidden display mode -q, used by python speed benchmark */
|
||||||
double cSpeed = ((double)srcSize / fastestC) * 1000;
|
double const cSpeed = ((double)srcSize / fastestC) * 1000;
|
||||||
double dSpeed = ((double)srcSize / fastestD) * 1000;
|
double const dSpeed = ((double)srcSize / fastestD) * 1000;
|
||||||
if (g_additionalParam)
|
if (g_additionalParam)
|
||||||
DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName, g_additionalParam);
|
DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName, g_additionalParam);
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user