Use ncount=1 when < 4096 symbols
This commit is contained in:
+3
-1
@@ -137,10 +137,12 @@ FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize
|
|||||||
/*! FSE_normalizeCount():
|
/*! FSE_normalizeCount():
|
||||||
normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
|
normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
|
||||||
'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).
|
'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).
|
||||||
|
useLowProbCount is a bool param which is set to 1 to use count=-1 or set to 0 to
|
||||||
|
use count=1 instead, which speeds up FSE_readNCount() and FSE_buildDTable().
|
||||||
@return : tableLog,
|
@return : tableLog,
|
||||||
or an errorCode, which can be tested using FSE_isError() */
|
or an errorCode, which can be tested using FSE_isError() */
|
||||||
FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog,
|
FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog,
|
||||||
const unsigned* count, size_t srcSize, unsigned maxSymbolValue);
|
const unsigned* count, size_t srcSize, unsigned maxSymbolValue, unsigned useLowProbCount);
|
||||||
|
|
||||||
/*! FSE_NCountWriteBound():
|
/*! FSE_NCountWriteBound():
|
||||||
Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.
|
Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.
|
||||||
|
|||||||
@@ -341,13 +341,10 @@ unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
|
|||||||
return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
|
return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Emit -1 based on # of symbols
|
|
||||||
#define LOW_PROB 0
|
|
||||||
|
|
||||||
/* Secondary normalization method.
|
/* Secondary normalization method.
|
||||||
To be used when primary method fails. */
|
To be used when primary method fails. */
|
||||||
|
|
||||||
static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
|
static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue, short lowProbCount)
|
||||||
{
|
{
|
||||||
short const NOT_YET_ASSIGNED = -2;
|
short const NOT_YET_ASSIGNED = -2;
|
||||||
U32 s;
|
U32 s;
|
||||||
@@ -363,8 +360,8 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
|
|||||||
norm[s]=0;
|
norm[s]=0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (LOW_PROB && count[s] <= lowThreshold) {
|
if (count[s] <= lowThreshold) {
|
||||||
norm[s] = -1;
|
norm[s] = lowProbCount;
|
||||||
distributed++;
|
distributed++;
|
||||||
total -= count[s];
|
total -= count[s];
|
||||||
continue;
|
continue;
|
||||||
@@ -435,7 +432,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
|
|||||||
|
|
||||||
size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
||||||
const unsigned* count, size_t total,
|
const unsigned* count, size_t total,
|
||||||
unsigned maxSymbolValue)
|
unsigned maxSymbolValue, unsigned useLowProbCount)
|
||||||
{
|
{
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
|
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
|
||||||
@@ -444,6 +441,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
|||||||
if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
|
if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
|
||||||
|
|
||||||
{ static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
|
{ static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
|
||||||
|
short const lowProbCount = useLowProbCount ? -1 : 1;
|
||||||
U64 const scale = 62 - tableLog;
|
U64 const scale = 62 - tableLog;
|
||||||
U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */
|
U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */
|
||||||
U64 const vStep = 1ULL<<(scale-20);
|
U64 const vStep = 1ULL<<(scale-20);
|
||||||
@@ -456,8 +454,8 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
|||||||
for (s=0; s<=maxSymbolValue; s++) {
|
for (s=0; s<=maxSymbolValue; s++) {
|
||||||
if (count[s] == total) return 0; /* rle special case */
|
if (count[s] == total) return 0; /* rle special case */
|
||||||
if (count[s] == 0) { normalizedCounter[s]=0; continue; }
|
if (count[s] == 0) { normalizedCounter[s]=0; continue; }
|
||||||
if (LOW_PROB && count[s] <= lowThreshold) {
|
if (count[s] <= lowThreshold) {
|
||||||
normalizedCounter[s] = -1;
|
normalizedCounter[s] = lowProbCount;
|
||||||
stillToDistribute--;
|
stillToDistribute--;
|
||||||
} else {
|
} else {
|
||||||
short proba = (short)((count[s]*step) >> scale);
|
short proba = (short)((count[s]*step) >> scale);
|
||||||
@@ -471,7 +469,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
|||||||
} }
|
} }
|
||||||
if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
|
if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
|
||||||
/* corner case, need another normalization method */
|
/* corner case, need another normalization method */
|
||||||
size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
|
size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue, lowProbCount);
|
||||||
if (FSE_isError(errorCode)) return errorCode;
|
if (FSE_isError(errorCode)) return errorCode;
|
||||||
}
|
}
|
||||||
else normalizedCounter[largest] += (short)stillToDistribute;
|
else normalizedCounter[largest] += (short)stillToDistribute;
|
||||||
@@ -643,7 +641,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
|
|||||||
}
|
}
|
||||||
|
|
||||||
tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
|
tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
|
||||||
CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
|
CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue, /* useLowProbCount */ srcSize >= 2048) );
|
||||||
|
|
||||||
/* Write table description header */
|
/* Write table description header */
|
||||||
{ CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
|
{ CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
|
|||||||
}
|
}
|
||||||
|
|
||||||
tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
|
tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
|
||||||
CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
|
CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) );
|
||||||
|
|
||||||
/* Write table description header */
|
/* Write table description header */
|
||||||
{ CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), norm, maxSymbolValue, tableLog) );
|
{ CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), norm, maxSymbolValue, tableLog) );
|
||||||
|
|||||||
@@ -50,6 +50,19 @@ static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
|
|||||||
return maxSymbolValue;
|
return maxSymbolValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if we should use ncount=-1 else we should
|
||||||
|
* use ncount=1 for low probability symbols instead.
|
||||||
|
*/
|
||||||
|
static unsigned ZSTD_useLowProbCount(size_t const nbSeq)
|
||||||
|
{
|
||||||
|
/* Heuristic: This should cover most blocks <= 16K and
|
||||||
|
* start to fade out after 16K to about 32K depending on
|
||||||
|
* comprssibility.
|
||||||
|
*/
|
||||||
|
return nbSeq >= 2048;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cost in bytes of encoding the normalized count header.
|
* Returns the cost in bytes of encoding the normalized count header.
|
||||||
* Returns an error if any of the helper functions return an error.
|
* Returns an error if any of the helper functions return an error.
|
||||||
@@ -60,7 +73,7 @@ static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
|
|||||||
BYTE wksp[FSE_NCOUNTBOUND];
|
BYTE wksp[FSE_NCOUNTBOUND];
|
||||||
S16 norm[MaxSeq + 1];
|
S16 norm[MaxSeq + 1];
|
||||||
const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
|
const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
|
||||||
FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max), "");
|
FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), "");
|
||||||
return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
|
return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +266,7 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
|||||||
nbSeq_1--;
|
nbSeq_1--;
|
||||||
}
|
}
|
||||||
assert(nbSeq_1 > 1);
|
assert(nbSeq_1 > 1);
|
||||||
FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max), "");
|
FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
|
||||||
{ size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
|
{ size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
|
||||||
FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
|
FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
|
||||||
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), "");
|
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), "");
|
||||||
|
|||||||
@@ -376,14 +376,14 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
|
|||||||
|
|
||||||
U16* symbolNext = (U16*)wksp;
|
U16* symbolNext = (U16*)wksp;
|
||||||
BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1);
|
BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1);
|
||||||
|
U32 highThreshold = tableSize - 1;
|
||||||
|
|
||||||
assert(wkspSize >= ZSTD_BUILD_FSE_TABLE_WKSP_SIZE);
|
|
||||||
(void)wkspSize;
|
|
||||||
|
|
||||||
/* Sanity Checks */
|
/* Sanity Checks */
|
||||||
assert(maxSymbolValue <= MaxSeq);
|
assert(maxSymbolValue <= MaxSeq);
|
||||||
assert(tableLog <= MaxFSELog);
|
assert(tableLog <= MaxFSELog);
|
||||||
U32 highThreshold = tableSize - 1;
|
assert(wkspSize >= ZSTD_BUILD_FSE_TABLE_WKSP_SIZE);
|
||||||
|
(void)wkspSize;
|
||||||
/* Init, lay down lowprob symbols */
|
/* Init, lay down lowprob symbols */
|
||||||
{ ZSTD_seqSymbol_header DTableH;
|
{ ZSTD_seqSymbol_header DTableH;
|
||||||
DTableH.tableLog = tableLog;
|
DTableH.tableLog = tableLog;
|
||||||
|
|||||||
@@ -786,7 +786,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
/* note : the result of this phase should be used to better appreciate the impact on statistics */
|
/* note : the result of this phase should be used to better appreciate the impact on statistics */
|
||||||
|
|
||||||
total=0; for (u=0; u<=offcodeMax; u++) total+=offcodeCount[u];
|
total=0; for (u=0; u<=offcodeMax; u++) total+=offcodeCount[u];
|
||||||
errorCode = FSE_normalizeCount(offcodeNCount, Offlog, offcodeCount, total, offcodeMax);
|
errorCode = FSE_normalizeCount(offcodeNCount, Offlog, offcodeCount, total, offcodeMax, /* useLowProbCount */ 1);
|
||||||
if (FSE_isError(errorCode)) {
|
if (FSE_isError(errorCode)) {
|
||||||
eSize = errorCode;
|
eSize = errorCode;
|
||||||
DISPLAYLEVEL(1, "FSE_normalizeCount error with offcodeCount \n");
|
DISPLAYLEVEL(1, "FSE_normalizeCount error with offcodeCount \n");
|
||||||
@@ -795,7 +795,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
Offlog = (U32)errorCode;
|
Offlog = (U32)errorCode;
|
||||||
|
|
||||||
total=0; for (u=0; u<=MaxML; u++) total+=matchLengthCount[u];
|
total=0; for (u=0; u<=MaxML; u++) total+=matchLengthCount[u];
|
||||||
errorCode = FSE_normalizeCount(matchLengthNCount, mlLog, matchLengthCount, total, MaxML);
|
errorCode = FSE_normalizeCount(matchLengthNCount, mlLog, matchLengthCount, total, MaxML, /* useLowProbCount */ 1);
|
||||||
if (FSE_isError(errorCode)) {
|
if (FSE_isError(errorCode)) {
|
||||||
eSize = errorCode;
|
eSize = errorCode;
|
||||||
DISPLAYLEVEL(1, "FSE_normalizeCount error with matchLengthCount \n");
|
DISPLAYLEVEL(1, "FSE_normalizeCount error with matchLengthCount \n");
|
||||||
@@ -804,7 +804,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
mlLog = (U32)errorCode;
|
mlLog = (U32)errorCode;
|
||||||
|
|
||||||
total=0; for (u=0; u<=MaxLL; u++) total+=litLengthCount[u];
|
total=0; for (u=0; u<=MaxLL; u++) total+=litLengthCount[u];
|
||||||
errorCode = FSE_normalizeCount(litLengthNCount, llLog, litLengthCount, total, MaxLL);
|
errorCode = FSE_normalizeCount(litLengthNCount, llLog, litLengthCount, total, MaxLL, /* useLowProbCount */ 1);
|
||||||
if (FSE_isError(errorCode)) {
|
if (FSE_isError(errorCode)) {
|
||||||
eSize = errorCode;
|
eSize = errorCode;
|
||||||
DISPLAYLEVEL(1, "FSE_normalizeCount error with litLengthCount \n");
|
DISPLAYLEVEL(1, "FSE_normalizeCount error with litLengthCount \n");
|
||||||
|
|||||||
+3
-3
@@ -1573,11 +1573,11 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
|||||||
const void* const contentStart = (const char*)dict + flatdictSize;
|
const void* const contentStart = (const char*)dict + flatdictSize;
|
||||||
size_t const target_nodict_cSize[22+1] = { 3840, 3770, 3870, 3830, 3770,
|
size_t const target_nodict_cSize[22+1] = { 3840, 3770, 3870, 3830, 3770,
|
||||||
3770, 3770, 3770, 3750, 3750,
|
3770, 3770, 3770, 3750, 3750,
|
||||||
3740, 3670, 3670, 3660, 3660,
|
3742, 3670, 3670, 3660, 3660,
|
||||||
3660, 3660, 3660, 3660, 3660,
|
3660, 3660, 3660, 3660, 3660,
|
||||||
3660, 3660, 3660 };
|
3660, 3660, 3660 };
|
||||||
size_t const target_wdict_cSize[22+1] = { 2830, 2890, 2890, 2820, 2940,
|
size_t const target_wdict_cSize[22+1] = { 2830, 2890, 2890, 2820, 2940,
|
||||||
2950, 2950, 2920, 2900, 2890,
|
2950, 2950, 2921, 2900, 2891,
|
||||||
2910, 2910, 2910, 2770, 2760,
|
2910, 2910, 2910, 2770, 2760,
|
||||||
2750, 2750, 2750, 2750, 2750,
|
2750, 2750, 2750, 2750, 2750,
|
||||||
2750, 2750, 2750 };
|
2750, 2750, 2750 };
|
||||||
@@ -2744,7 +2744,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
|||||||
/* Calling FSE_normalizeCount() on a uniform distribution should not
|
/* Calling FSE_normalizeCount() on a uniform distribution should not
|
||||||
* cause a division by zero.
|
* cause a division by zero.
|
||||||
*/
|
*/
|
||||||
FSE_normalizeCount(norm, tableLog, count, nbSeq, maxSymbolValue);
|
FSE_normalizeCount(norm, tableLog, count, nbSeq, maxSymbolValue, /* useLowProbCount */ 1);
|
||||||
}
|
}
|
||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
#ifdef ZSTD_MULTITHREAD
|
#ifdef ZSTD_MULTITHREAD
|
||||||
|
|||||||
Reference in New Issue
Block a user