Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ff79dbe94 | ||
|
|
58b3ef79eb | ||
|
|
ca498343dd | ||
|
|
136a16dd8b |
@@ -77,7 +77,7 @@ EXPORT_SYMBOL(zstd_init_dstream);
|
|||||||
|
|
||||||
size_t zstd_reset_dstream(zstd_dstream *dstream)
|
size_t zstd_reset_dstream(zstd_dstream *dstream)
|
||||||
{
|
{
|
||||||
return ZSTD_resetDStream(dstream);
|
return ZSTD_DCtx_reset(dstream, ZSTD_reset_session_only);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(zstd_reset_dstream);
|
EXPORT_SYMBOL(zstd_reset_dstream);
|
||||||
|
|
||||||
|
|||||||
@@ -115,11 +115,7 @@ static uint64_t ZSTD_div64(uint64_t dividend, uint32_t divisor) {
|
|||||||
#ifndef ZSTD_DEPS_STDINT
|
#ifndef ZSTD_DEPS_STDINT
|
||||||
#define ZSTD_DEPS_STDINT
|
#define ZSTD_DEPS_STDINT
|
||||||
|
|
||||||
/*
|
/* intptr_t already provided by ZSTD_DEPS_COMMON */
|
||||||
* The Linux Kernel doesn't provide intptr_t, only uintptr_t, which
|
|
||||||
* is an unsigned long.
|
|
||||||
*/
|
|
||||||
typedef long intptr_t;
|
|
||||||
|
|
||||||
#endif /* ZSTD_DEPS_STDINT */
|
#endif /* ZSTD_DEPS_STDINT */
|
||||||
#endif /* ZSTD_DEPS_NEED_STDINT */
|
#endif /* ZSTD_DEPS_NEED_STDINT */
|
||||||
|
|||||||
@@ -169,6 +169,10 @@ The file structure is designed to make this selection manually achievable for an
|
|||||||
`ZSTDERRORLIB_VSIBILITY`, and `ZDICTLIB_VISIBILITY` if unset, for backwards compatibility
|
`ZSTDERRORLIB_VSIBILITY`, and `ZDICTLIB_VISIBILITY` if unset, for backwards compatibility
|
||||||
with the old macro names.
|
with the old macro names.
|
||||||
|
|
||||||
|
- The C compiler macro `HUF_DISABLE_FAST_DECODE` disables the newer Huffman fast C
|
||||||
|
and assembly decoding loops. You may want to use this macro if these loops are
|
||||||
|
slower on your platform.
|
||||||
|
|
||||||
#### Windows : using MinGW+MSYS to create DLL
|
#### Windows : using MinGW+MSYS to create DLL
|
||||||
|
|
||||||
DLL can be created using MinGW+MSYS with the `make libzstd` command.
|
DLL can be created using MinGW+MSYS with the `make libzstd` command.
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
short ncount[FSE_MAX_SYMBOL_VALUE + 1];
|
short ncount[FSE_MAX_SYMBOL_VALUE + 1];
|
||||||
FSE_DTable dtable[1]; /* Dynamically sized */
|
FSE_DTable dtable[]; /* Dynamically sized */
|
||||||
} FSE_DecompressWksp;
|
} FSE_DecompressWksp;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+103
-64
@@ -34,6 +34,12 @@
|
|||||||
* Macros
|
* Macros
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
|
#ifdef HUF_DISABLE_FAST_DECODE
|
||||||
|
# define HUF_ENABLE_FAST_DECODE 0
|
||||||
|
#else
|
||||||
|
# define HUF_ENABLE_FAST_DECODE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* These two optional macros force the use one way or another of the two
|
/* These two optional macros force the use one way or another of the two
|
||||||
* Huffman decompression implementations. You can't force in both directions
|
* Huffman decompression implementations. You can't force in both directions
|
||||||
* at the same time.
|
* at the same time.
|
||||||
@@ -292,6 +298,24 @@ static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressFastArg
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calls X(N) for each stream 0, 1, 2, 3. */
|
||||||
|
#define HUF_4X_FOR_EACH_STREAM(X) \
|
||||||
|
{ \
|
||||||
|
X(0) \
|
||||||
|
X(1) \
|
||||||
|
X(2) \
|
||||||
|
X(3) \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calls X(N, var) for each stream 0, 1, 2, 3. */
|
||||||
|
#define HUF_4X_FOR_EACH_STREAM_WITH_VAR(X, var) \
|
||||||
|
{ \
|
||||||
|
X(0, (var)) \
|
||||||
|
X(1, (var)) \
|
||||||
|
X(2, (var)) \
|
||||||
|
X(3, (var)) \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef HUF_FORCE_DECOMPRESS_X2
|
#ifndef HUF_FORCE_DECOMPRESS_X2
|
||||||
|
|
||||||
@@ -705,7 +729,6 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
BYTE* olimit;
|
BYTE* olimit;
|
||||||
int stream;
|
int stream;
|
||||||
int symbol;
|
|
||||||
|
|
||||||
/* Assert loop preconditions */
|
/* Assert loop preconditions */
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@@ -752,27 +775,42 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol) \
|
||||||
|
{ \
|
||||||
|
int const index = (int)(bits[(_stream)] >> 53); \
|
||||||
|
int const entry = (int)dtable[index]; \
|
||||||
|
bits[(_stream)] <<= (entry & 0x3F); \
|
||||||
|
op[(_stream)][(_symbol)] = (BYTE)((entry >> 8) & 0xFF); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HUF_4X1_RELOAD_STREAM(_stream) \
|
||||||
|
{ \
|
||||||
|
int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
||||||
|
int const nbBits = ctz & 7; \
|
||||||
|
int const nbBytes = ctz >> 3; \
|
||||||
|
op[(_stream)] += 5; \
|
||||||
|
ip[(_stream)] -= nbBytes; \
|
||||||
|
bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \
|
||||||
|
bits[(_stream)] <<= nbBits; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Manually unroll the loop because compilers don't consistently
|
||||||
|
* unroll the inner loops, which destroys performance.
|
||||||
|
*/
|
||||||
do {
|
do {
|
||||||
/* Decode 5 symbols in each of the 4 streams */
|
/* Decode 5 symbols in each of the 4 streams */
|
||||||
for (symbol = 0; symbol < 5; ++symbol) {
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 0)
|
||||||
for (stream = 0; stream < 4; ++stream) {
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 1)
|
||||||
int const index = (int)(bits[stream] >> 53);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 2)
|
||||||
int const entry = (int)dtable[index];
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 3)
|
||||||
bits[stream] <<= (entry & 63);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 4)
|
||||||
op[stream][symbol] = (BYTE)((entry >> 8) & 0xFF);
|
|
||||||
}
|
/* Reload each of the 4 the bitstreams */
|
||||||
}
|
HUF_4X_FOR_EACH_STREAM(HUF_4X1_RELOAD_STREAM)
|
||||||
/* Reload the bitstreams */
|
|
||||||
for (stream = 0; stream < 4; ++stream) {
|
|
||||||
int const ctz = ZSTD_countTrailingZeros64(bits[stream]);
|
|
||||||
int const nbBits = ctz & 7;
|
|
||||||
int const nbBytes = ctz >> 3;
|
|
||||||
op[stream] += 5;
|
|
||||||
ip[stream] -= nbBytes;
|
|
||||||
bits[stream] = MEM_read64(ip[stream]) | 1;
|
|
||||||
bits[stream] <<= nbBits;
|
|
||||||
}
|
|
||||||
} while (op[3] < olimit);
|
} while (op[3] < olimit);
|
||||||
|
|
||||||
|
#undef HUF_4X1_DECODE_SYMBOL
|
||||||
|
#undef HUF_4X1_RELOAD_STREAM
|
||||||
}
|
}
|
||||||
|
|
||||||
_out:
|
_out:
|
||||||
@@ -868,7 +906,7 @@ static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(flags & HUF_flags_disableFast)) {
|
if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) {
|
||||||
size_t const ret = HUF_decompress4X1_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
|
size_t const ret = HUF_decompress4X1_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1490,7 +1528,6 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
BYTE* olimit;
|
BYTE* olimit;
|
||||||
int stream;
|
int stream;
|
||||||
int symbol;
|
|
||||||
|
|
||||||
/* Assert loop preconditions */
|
/* Assert loop preconditions */
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@@ -1547,54 +1584,56 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3) \
|
||||||
|
if ((_decode3) || (_stream) != 3) { \
|
||||||
|
int const index = (int)(bits[(_stream)] >> 53); \
|
||||||
|
HUF_DEltX2 const entry = dtable[index]; \
|
||||||
|
MEM_write16(op[(_stream)], entry.sequence); \
|
||||||
|
bits[(_stream)] <<= (entry.nbBits) & 0x3F; \
|
||||||
|
op[(_stream)] += (entry.length); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HUF_4X2_RELOAD_STREAM(_stream) \
|
||||||
|
{ \
|
||||||
|
HUF_4X2_DECODE_SYMBOL(3, 1) \
|
||||||
|
{ \
|
||||||
|
int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
||||||
|
int const nbBits = ctz & 7; \
|
||||||
|
int const nbBytes = ctz >> 3; \
|
||||||
|
ip[(_stream)] -= nbBytes; \
|
||||||
|
bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \
|
||||||
|
bits[(_stream)] <<= nbBits; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Manually unroll the loop because compilers don't consistently
|
||||||
|
* unroll the inner loops, which destroys performance.
|
||||||
|
*/
|
||||||
do {
|
do {
|
||||||
/* Do 5 table lookups for each of the first 3 streams */
|
/* Decode 5 symbols from each of the first 3 streams.
|
||||||
for (symbol = 0; symbol < 5; ++symbol) {
|
* The final stream will be decoded during the reload phase
|
||||||
for (stream = 0; stream < 3; ++stream) {
|
* to reduce register pressure.
|
||||||
int const index = (int)(bits[stream] >> 53);
|
|
||||||
HUF_DEltX2 const entry = dtable[index];
|
|
||||||
MEM_write16(op[stream], entry.sequence);
|
|
||||||
bits[stream] <<= (entry.nbBits);
|
|
||||||
op[stream] += (entry.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Do 1 table lookup from the final stream */
|
|
||||||
{
|
|
||||||
int const index = (int)(bits[3] >> 53);
|
|
||||||
HUF_DEltX2 const entry = dtable[index];
|
|
||||||
MEM_write16(op[3], entry.sequence);
|
|
||||||
bits[3] <<= (entry.nbBits);
|
|
||||||
op[3] += (entry.length);
|
|
||||||
}
|
|
||||||
/* Do 4 table lookups from the final stream & reload bitstreams */
|
|
||||||
for (stream = 0; stream < 4; ++stream) {
|
|
||||||
/* Do a table lookup from the final stream.
|
|
||||||
* This is interleaved with the reloading to reduce register
|
|
||||||
* pressure. This shouldn't be necessary, but compilers can
|
|
||||||
* struggle with codegen with high register pressure.
|
|
||||||
*/
|
*/
|
||||||
{
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0)
|
||||||
int const index = (int)(bits[3] >> 53);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0)
|
||||||
HUF_DEltX2 const entry = dtable[index];
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0)
|
||||||
MEM_write16(op[3], entry.sequence);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0)
|
||||||
bits[3] <<= (entry.nbBits);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0)
|
||||||
op[3] += (entry.length);
|
|
||||||
}
|
/* Decode one symbol from the final stream */
|
||||||
/* Reload the bistreams. The final bitstream must be reloaded
|
HUF_4X2_DECODE_SYMBOL(3, 1)
|
||||||
* after the 5th symbol was decoded.
|
|
||||||
|
/* Decode 4 symbols from the final stream & reload bitstreams.
|
||||||
|
* The final stream is reloaded last, meaning that all 5 symbols
|
||||||
|
* are decoded from the final stream before it is reloaded.
|
||||||
*/
|
*/
|
||||||
{
|
HUF_4X_FOR_EACH_STREAM(HUF_4X2_RELOAD_STREAM)
|
||||||
int const ctz = ZSTD_countTrailingZeros64(bits[stream]);
|
|
||||||
int const nbBits = ctz & 7;
|
|
||||||
int const nbBytes = ctz >> 3;
|
|
||||||
ip[stream] -= nbBytes;
|
|
||||||
bits[stream] = MEM_read64(ip[stream]) | 1;
|
|
||||||
bits[stream] <<= nbBits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (op[3] < olimit);
|
} while (op[3] < olimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef HUF_4X2_DECODE_SYMBOL
|
||||||
|
#undef HUF_4X2_RELOAD_STREAM
|
||||||
|
|
||||||
_out:
|
_out:
|
||||||
|
|
||||||
/* Save the final values of each of the state variables back to args. */
|
/* Save the final values of each of the state variables back to args. */
|
||||||
@@ -1679,7 +1718,7 @@ static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(flags & HUF_flags_disableFast)) {
|
if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) {
|
||||||
size_t const ret = HUF_decompress4X2_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
|
size_t const ret = HUF_decompress4X2_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
Reference in New Issue
Block a user