Skip to content

Commit 2543295

Browse files
committed
Slightly improve entropy performance
1 parent 81f6313 commit 2543295

File tree

3 files changed

+43
-29
lines changed

3 files changed

+43
-29
lines changed

lib/common/bits.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,29 @@ MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCo
172172
return 31 - ZSTD_countLeadingZeros32(val);
173173
}
174174

175+
/* ZSTD_rotateRight_*():
176+
* Rotates a bitfield to the right by "count" bits.
177+
* https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts
178+
*/
179+
FORCE_INLINE_TEMPLATE
180+
U64 ZSTD_rotateRight_U64(U64 const value, U32 count) {
181+
assert(count < 64);
182+
count &= 0x3F; /* for fickle pattern recognition */
183+
return (value >> count) | (U64)(value << ((0U - count) & 0x3F));
184+
}
185+
186+
FORCE_INLINE_TEMPLATE
187+
U32 ZSTD_rotateRight_U32(U32 const value, U32 count) {
188+
assert(count < 32);
189+
count &= 0x1F; /* for fickle pattern recognition */
190+
return (value >> count) | (U32)(value << ((0U - count) & 0x1F));
191+
}
192+
193+
FORCE_INLINE_TEMPLATE
194+
U16 ZSTD_rotateRight_U16(U16 const value, U32 count) {
195+
assert(count < 16);
196+
count &= 0x0F; /* for fickle pattern recognition */
197+
return (value >> count) | (U16)(value << ((0U - count) & 0x0F));
198+
}
199+
175200
#endif /* ZSTD_BITS_H */

lib/compress/zstd_compress.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "zstd_opt.h"
2828
#include "zstd_ldm.h"
2929
#include "zstd_compress_superblock.h"
30-
#include "../common/bits.h" /* ZSTD_highbit32 */
30+
#include "../common/bits.h" /* ZSTD_highbit32, ZSTD_rotateRight_U64 */
3131

3232
/* ***************************************************************
3333
* Tuning parameters
@@ -1884,6 +1884,19 @@ typedef enum {
18841884
ZSTD_resetTarget_CCtx
18851885
} ZSTD_resetTarget_e;
18861886

1887+
/* Mixes bits in a 64 bits in a value, based on XXH3_rrmxmx */
1888+
static U64 ZSTD_bitmix(U64 val, U64 len) {
1889+
val ^= ZSTD_rotateRight_U64(val, 49) ^ ZSTD_rotateRight_U64(val, 24);
1890+
val *= 0x9FB21C651E98DF25ULL;
1891+
val ^= (val >> 35) + len ;
1892+
val *= 0x9FB21C651E98DF25ULL;
1893+
return val ^ (val >> 28);
1894+
}
1895+
1896+
/* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */
1897+
static void ZSTD_advanceHashSalt(ZSTD_matchState_t* ms) {
1898+
ms->hashSalt = ZSTD_bitmix(ms->hashSalt, 8) ^ ZSTD_bitmix((U64) ms->hashSaltEntropy, 4);
1899+
}
18871900

18881901
static size_t
18891902
ZSTD_reset_matchState(ZSTD_matchState_t* ms,
@@ -1939,8 +1952,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
19391952
* 0 when we reset a Cdict */
19401953
if(forWho == ZSTD_resetTarget_CCtx) {
19411954
ms->tagTable = (U16 *) ZSTD_cwksp_reserve_aligned_init_once(ws, tagTableSize);
1942-
ms->hashSalt = (U64) ZSTD_hashPtr(&ms->hashSalt, 32, sizeof(ms->hashSalt)) << 32 |
1943-
ZSTD_hashPtr(&ms->hashSaltEntropy, 32, sizeof(ms->hashSaltEntropy));
1955+
ZSTD_advanceHashSalt(ms);
19441956
} else {
19451957
/* When we are not salting we want to always memset the memory */
19461958
ms->tagTable = (U16 *) ZSTD_cwksp_reserve_aligned(ws, tagTableSize);

lib/compress/zstd_lazy.c

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -774,31 +774,6 @@ MEM_STATIC U32 ZSTD_VecMask_next(ZSTD_VecMask val) {
774774
return ZSTD_countTrailingZeros64(val);
775775
}
776776

777-
/* ZSTD_rotateRight_*():
778-
* Rotates a bitfield to the right by "count" bits.
779-
* https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts
780-
*/
781-
FORCE_INLINE_TEMPLATE
782-
U64 ZSTD_rotateRight_U64(U64 const value, U32 count) {
783-
assert(count < 64);
784-
count &= 0x3F; /* for fickle pattern recognition */
785-
return (value >> count) | (U64)(value << ((0U - count) & 0x3F));
786-
}
787-
788-
FORCE_INLINE_TEMPLATE
789-
U32 ZSTD_rotateRight_U32(U32 const value, U32 count) {
790-
assert(count < 32);
791-
count &= 0x1F; /* for fickle pattern recognition */
792-
return (value >> count) | (U32)(value << ((0U - count) & 0x1F));
793-
}
794-
795-
FORCE_INLINE_TEMPLATE
796-
U16 ZSTD_rotateRight_U16(U16 const value, U32 count) {
797-
assert(count < 16);
798-
count &= 0x0F; /* for fickle pattern recognition */
799-
return (value >> count) | (U16)(value << ((0U - count) & 0x0F));
800-
}
801-
802777
/* ZSTD_row_nextIndex():
803778
* Returns the next index to insert at within a tagTable row, and updates the "head"
804779
* value to reflect the update. Essentially cycles backwards from [0, {entries per row})
@@ -891,6 +866,7 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internalImpl(ZSTD_matchState_t* ms,
891866
U32* const hashTable = ms->hashTable;
892867
U16* const tagTable = ms->tagTable;
893868
U32 const hashLog = ms->rowHashLog;
869+
U32 hashSaltEntropyCollected = 0;
894870
const BYTE* const base = ms->window.base;
895871

896872
DEBUGLOG(6, "ZSTD_row_update_internalImpl(): updateStartIdx=%u, updateEndIdx=%u", updateStartIdx, updateEndIdx);
@@ -906,8 +882,9 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internalImpl(ZSTD_matchState_t* ms,
906882
assert(hash == ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt));
907883
((BYTE*)tagRow)[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK;
908884
row[pos] = updateStartIdx;
909-
ms->hashSaltEntropy += hash;
885+
hashSaltEntropyCollected = hash;
910886
}
887+
ms->hashSaltEntropy += hashSaltEntropyCollected; /* collect salt entropy */
911888
}
912889

913890
/* ZSTD_row_update_internal():

0 commit comments

Comments
 (0)