变大听起来很奇怪,但这正是我要做的我想取16位整数的整个序列,并对每个整数进行散列,使其均匀地映射到256位空间。
原因是我试图将16位数字空间的一个子集放入256位bloom过滤器中,以进行快速的成员资格测试。
我可以在每个整数上使用一些众所周知的散列函数,但我正在寻找一个非常有效的实现(只是一些指令),以便在gpu着色器程序中运行良好。我觉得散列输入只有16位这一事实可以告诉哈希函数是以某种方式设计的,但是我没有看到解决方案。
有什么想法吗?
编辑
根据我的回答,我最初的问题令人困惑很抱歉。我将试图用一个更具体的例子来重申这一点:
我有集合S中n个数的一个子集S1,它在(0,2^16-1)的范围内我需要用一个256位bloom过滤器来表示这个子集S1,这个过滤器是用一个散列函数构造的布卢姆过滤器的原因是一个空间考虑。我选择了一个256位的bloom滤波器,因为它符合我的空间需求,并且具有足够低的误报概率。我正在寻找一个非常简单的散列函数,它可以从集合S中取一个数,并用256位表示,这样每一位的概率大致相等,可以是1或0。
hashing函数需要简单性的原因是,这个hashing函数必须每像素运行数千次,所以在任何可以修剪指令的地方都是成功的。

最佳答案

如果将16位值乘以2^31和2^32之间的素数(或任何奇数),则“可能”在32位空间上均匀地涂抹结果。然后,您可能需要添加另一个质数,以防止uint32_t映射到p(您希望每个位都有相同的00概率,2^256中只有一个输入值应该输出所有零,并且由于只有2^16个输入,这意味着您不希望它们都输出所有零)。
所以这就是如何用一个操作将16位扩展到32位(加上加载常数所需的任何指令)使用四个不同的值01获取256位,并使用不同的p1值运行一些测试以找到好的值(即,那些产生的误报不会比您期望的bloom过滤器多出太多,因为您正在编码的集的大小和假设的哈希函数是理想的)。例如,我很确定p4是一个坏的p值。
不过,不管这些值有多好,您都会看到一些相关性:例如,正如我在上面所描述的,所有4个独立值中的最低位都是相等的,这是一个相当严重的依赖关系。所以你可能需要更多的“混合”操作。例如,您可能会说,最终输出的每个字节都应该是我所描述的两个字节(而不是两个最小的siginfiant字节)的异或。,只是为了摆脱简单的算术关系。
不过,除非我误解了这个问题,否则这不是Bloom过滤器通常的工作方式通常,您希望哈希为每个输入生成一个确切的固定数量的设置位,所有计算假阳性率的算法都依赖于此这就是为什么对于大小为256位的bloom过滤器,通常会有p8位散列,而不是一个256位散列。-1通常小于滤波器大小的一半(以位为单位)(最佳值是滤波器中每个值的位数,乘以k约为0.7)。所以通常情况下,你不希望每个比特都是1的概率高达0.5。
原因是,一旦你将256位的值合在一起,你的过滤器中几乎所有的位都被设置了(15/16)所以你已经看到了很多误报。
但是,如果你已经完成了计算,并且你对一个散列函数产生一个平均一半的可变设置位感到满意,那么就足够了或者数字256的两次出现只是巧合,因为对于您选择的设置大小,k恰好是32,而您实际上使用的是256位散列作为32个8位散列?
[编辑:您的评论澄清了这一点,但无论如何ln(2)不应该太高,您总共需要256位散列显然,在这种情况下,使用每个值超过16位(即小于16个值)的Bloom过滤器是没有意义的,因为使用相同的空间,您可以只列出这些值,并且假阳性率为0每值16位的过滤器给出的假阳性率大约为2200分之一。即使在那里,optimalk也只有23位,也就是说,应该为集合中的每个值在过滤器中设置23位如果您希望集合大于16个值,那么您希望为每个元素设置更少的位,并且您将获得更高的假阳性率。]

关于c++ - 将16位整数哈希有效地哈希到256位空间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21080965/

10-09 09:33