【发布时间】:2015-06-18 19:50:13
【问题描述】:
我需要为大约 N=1 亿个键生成哈希键。从我的研究看来,murmur3(MurmurHash3_x86_32,参见murmur3 hash)将是最快的散列函数,具有最佳的延迟和足够小的碰撞率。我面临的问题是该函数将键返回为void *。更具体地说,模板是:
void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out);
由于我的哈希表大小会小于它可以生成的最大哈希值,我需要将它放入表范围 [0, N-1] 中。最简单的解决方案似乎是使用% 运算符。但由于它的操作速度很慢,我想知道是否有更快的方法来解决这个问题。
我发现一个有趣的建议是在 StackOverflow 本身上给出的 Is there an alternative to using % (modulus) in C/C++?。它暗示“二的幂,以下作品(假设二的补码表示)”:
return i & (n-1);
我的问题是,在较新的 CPU 上,有时(或者大多数时候?),由于多路缓存行,性能会在大约 2^n,IIRC 大小时下降。 (此链接提供了有关插入的说明 Big Memory, Part 3.5: Google sparsehash!)。
目前,murmur3 的优势似乎被硬件相关问题和% 运算符的已知效率低下所抵消。由于性能是一个限制因素,我要求低延迟和更快的解决方案来满足我的要求,即使它不是 MurmurHash3_x86_32。
【问题讨论】:
-
不要仅仅因为它很慢就避免使用
%运算符,如果您尝试将 128 位数字放入任意大小的空间中,您将很难做得更好。你还能举一个更好的例子来说明 2^n 左右的性能下降吗? -
您是否实际检查(分析)
%的成本与 murmur3 散列的成本相比较高? -
我认为您误解了“大内存,第 3.5 部分”中的性能下降。它们在那里是因为表格的对数增长。如果您预先分配整个表,您将看不到这一点。
-
查看igoro.com/archive/gallery-of-processor-cache-effects/… 了解有关缓存相关观察的详细信息。我还没有将 % 的性能作为给定的基准。
-
一个
%操作的性能与计算一个哈希值的成本相比是无关紧要的。
标签: c++ c hash modulo low-latency