C++:获取范围内整数的最快方法
C++: Quickest way to get integer within a range
我需要为大约 N=1 亿个密钥生成哈希键。根据我的研究,杂音3(MurmurHash3_x86_32,参见杂音3哈希)将是最快的散列函数,具有最佳延迟和足够小的碰撞率。我面临的问题是该函数将键返回为void *
。更具体地说,模板是:
void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out);
由于我的哈希表大小小于它可以生成的最大哈希,我需要将其放入表范围 [0, N-1]。最简单的解决方案似乎是使用%
运算符。但是众所周知,它是一个缓慢的运算符,我想知道是否有更快的方法来解决问题。
我发现的一个有趣的建议是有没有替代在C/C++中使用%(模量)的替代方案? 在StackOverflow本身上。它建议"二的幂,以下工作(假设二的补充表示)":
return i & (n-1);
我的问题是,在较新的 CPU 上,由于多路缓存行,有时(或者大多数时候?)性能在大小 2^n 左右下降,IIRC。(此链接提供了有关插入大内存的插图,第 3.5 部分:谷歌稀疏哈希!
目前,murmur3的优势似乎被硬件相关问题和已知的%
操作员效率低下所抵消。由于性能是一个限制,我要求低延迟和更快的解决方案来满足我的需求,即使它不是MurmurHash3_x86_32。
我面临的问题是该函数将键返回为
void *
.
它没有。 它不返回任何内容(void
)。 哈希结果通过最后一个参数记录在您指定的缓冲区(指针)中。 对于MurmurHash3_x86_32()
来说,最有意义的是指向uint32_t
的指针。
由于我的哈希表大小小于它可以生成的最大哈希,我需要将其放入表范围 [0, N-1]。最简单的解决方案似乎是使用 % 运算符。但是众所周知,它是一个缓慢的运算符,我想知道是否有更快的方法来解决问题。
%
不仅是最简单的解决方案,而且是最常见的解决方案。 "慢"是相对的——%
比+
慢,但比一次调用MurmurHash3_x86_32()
快得多。
我发现的一个有趣的建议[...]建议[使用2的幂表大小,并通过
&
运算符计算模数]
请注意,与 SO 答案中的断言相反,实际上这与 twos 的补码表示完全没有依赖关系。
我的问题是,在较新的 CPU 上,由于多路缓存行,有时(或者大多数时候?)性能在大小 2^n 左右下降,IIRC。(此链接提供了有关插入大内存的插图,第 3.5 部分:谷歌稀疏哈希!
您链接的报告中描述的性能降级归因于重新哈希,这似乎很有道理。 这与您所询问的操作无关。 可以想象,缓存(缺乏)关联性可能会影响大型哈希表的性能,但可能不会比通常具有大型哈希表的影响更大。 使用哈希表时固有的内存访问模式自然会产生较差的缓存局部性。 这实际上就是重点。
目前,murmur3的优势似乎被硬件相关问题和%运算符的已知低效率所抵消。由于性能是一个限制,我要求低延迟和更快的解决方案来满足我的需求,即使它不是MurmurHash3_x86_32。
你想多了。 无法有效利用 CPU 缓存只是您使用大型哈希表所付出的代价。 它不与哈希函数相关联(只要哈希函数很好地完成其工作)。 单个算术运算的成本,无论是%
还是&
,与计算要操作的哈希的成本相比,都不会明显,因此选择哪一个并不重要。如果您希望该操作具有微小的优势,请使用 2 次幂大小的表和 &
运算符。 另一方面,这扔掉了一些你费了这么多钱计算的哈希位。 考虑选择主要哈希表大小和%
运算符 - 然后所有哈希位都将有助于存储桶选择,这可能会改善您的点差。
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 让bool方法返回其他整数
- 有没有一种优雅而快速的方法来测试整数中的 1 位是否位于连续区域
- 将一系列整数放入类的最佳方法是什么?
- 比较C++中两个整数的最有效和最干净的方法是什么?
- 在 C++ 中将整数数组转换为位集表示形式的最佳方法?
- 有没有更好的方法对C++中的三个整数进行排序?
- 使用192/256位整数求和无符号64位整数向量的点积的最快方法
- 初始化不是整数的巨大常量多维数组的最佳方法是什么?
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- C++:这是使用整数变量作为函数调用指针的正确方法吗
- 计算将整数n分解为4平方和的方法的数量
- 计算机使用什么方法添加无符号整数
- 基于整数向量执行位排列的有效方法?
- 快速方法可以将整数乘以适当的分数,而无需浮点或溢出
- 为大无符号整数分配内存的有效方法
- 在模型中保存整数的方法,与QStyledItemDelegate兼容
- 将整数输入数组的方法比 scanf() 或 cin 更快?
- 如何将枚举传递给方法而不将其作为整数传递
- 获取两个无符号整数 C++ 乘积的高 32 位的有效方法