mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-10 17:17:06 +02:00
MINOR: tools: improve ptr hash distribution on 64 bits
When testing the pointer hash on 64-bit real pointers (map entries), it appeared that the shift by 33 bits that hoped to compensate for the 3 nul LSB degrades the hash, and the centering is more optimal on 31-(bits+1)/2. This makes sense since the topmost bit of the multiplicator is 31, so for an input of 1 bit and 1 bit of output we would always get zero. With the formula adjusted this way, we can get up to ~15% more unique entries at 10 bits and ~24% more at 11 bits.
This commit is contained in:
parent
ab6cb5dea0
commit
58946d44f8
@ -1085,12 +1085,13 @@ static inline uint statistical_prng_range(uint range)
|
|||||||
* to compute statistic buckets, in that it's fast and reasonably distributed
|
* to compute statistic buckets, in that it's fast and reasonably distributed
|
||||||
* thanks to mixing the bits via a multiplication by a prime number and using
|
* thanks to mixing the bits via a multiplication by a prime number and using
|
||||||
* the middle bits on 64-bit platforms or remixing the topmost with lowest ones
|
* the middle bits on 64-bit platforms or remixing the topmost with lowest ones
|
||||||
* on 32-bit. It provides ~2588 unique values (~1510 non-colliding) at 100%
|
* on 32-bit. It provides ~2491 unique values (~1354 non-colliding) for 2^12
|
||||||
* fill ratio for 12 bits, ~1296 (~756 non-colliding) at 100% fill ratio for 11
|
* valid pointers at 12 bits, ~1454 (~941 non-colliding) for 2^11 valid ptrs
|
||||||
* bits, ~648 (~378 non-colliding) at 100% fill ratio for 10 bits, ~163 (95 non
|
* at 11 bits, ~707 (~434 non-colliding) for 2^10 valid ptrs at 10 bits, ~347
|
||||||
* colliding) at 100% fill ratio for 8 bits, hence 1-1/e and 1/e respectively.
|
* (212 non colliding) for 2^9 valid ptrs at 9 bits, and 165/99 for 2^8 ptrs
|
||||||
* It must be inlined so that <bits> is always a compile-time constant. It
|
* at 8 bits, hence 1-1/e and 1/e respectively. It must be inlined so that
|
||||||
* supports output sizes from 0 to 32 bits.
|
* <bits> is always a compile-time constant. It supports output sizes from 0
|
||||||
|
* to 32 bits.
|
||||||
*/
|
*/
|
||||||
static forceinline uint ptr_hash(const void *p, const int bits)
|
static forceinline uint ptr_hash(const void *p, const int bits)
|
||||||
{
|
{
|
||||||
@ -1103,7 +1104,7 @@ static forceinline uint ptr_hash(const void *p, const int bits)
|
|||||||
if (sizeof(long) == 4)
|
if (sizeof(long) == 4)
|
||||||
x ^= x >> 32;
|
x ^= x >> 32;
|
||||||
else
|
else
|
||||||
x >>= 33 - bits / 2;
|
x >>= 31 - (bits + 1) / 2;
|
||||||
return x & (~0U >> (-bits & 31));
|
return x & (~0U >> (-bits & 31));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user