获取特殊素数的浮点数模的快速、可向量化方法?
Posted
技术标签:
【中文标题】获取特殊素数的浮点数模的快速、可向量化方法?【英文标题】:Fast, Vectorizable method of taking floating point number modulus of special primes? 【发布时间】:2010-03-16 19:58:13 【问题描述】:有没有一种快速取浮点数模数的方法?
对于整数,梅森素数有一些技巧,因此可以计算 y = x MOD 2^31-1 而无需除法。 integer trick
可以对浮点数应用任何类似的技巧吗?
最好以可以转换为向量/SIMD 操作或移动到 GPGPU 代码的方式进行。这排除了对浮点数据使用整数计算。
我感兴趣的素数是 2^7-1 和 2^31-1,但如果浮点数有更有效的素数,那将是受欢迎的。
此算法的一个预期用途是在输入浮点数被读入算法时计算它们的运行“校验和”。为了避免占用过多的计算能力,我想保持这种轻量级。
显然,类似的技术用于更大的数字,特别是 2^127 - 1。不幸的是,论文中的数学超出了我的能力,我无法弄清楚如何将其转换为更小的素数。Example of floating point MOD 2^127 - 1 - HASH127
【问题讨论】:
无需除法即可计算任何二次方的模数;你确定你问的是你打算问的问题吗?我相信您实际上是在寻找计算模块2^7 - 1
和 2^31 - 1
。
2^7 和 2^31 不是素数 - 你能更准确地重新表述你的问题吗?
您的目标是哪些指令集?
是的,x 和 y 中的值应该是整数。首先,我想在 Windows 上定位向量内在函数(那些有整数支持,但速度很慢)。最终我会转向 ATI 图形 (CTM API),它只有 16 位/32 位 FP。
【参考方案1】:
我查看了 djb 的论文,发现它更容易了,因为 31 位很适合 53 位精度双有效位。假设您的校验和由 Z/(2**31 - 1) 上的一些环运算组成,解决计算 x mod Z/(2**31 - 1);最后,您可以使用整数算术来找到一个规范的,这很慢,但不应该经常发生。
基本的归约步骤是将整数 x = y + 2**31 * z 替换为 y + z。 djb 使用的技巧是计算 w = (x + L) - L,其中 L 是一个大整数,经过精心挑选,以便以 z = 2**-31 * w 的方式进行舍入。然后计算 y = x - w 并输出 y + z,其幅度最多为 2**32。 (如果此操作还不够,我深表歉意;如果是,请发布您的校验和算法。)
L 的选择涉及知道有效数字的精确程度。对于模数 2**31 - 1,我们希望最小精度单位 (ulp) 为 2**31。对于 [1.0, 2.0) 范围内的双精度数,ulp 为 2**-52,因此 L 应为 2**52 * 2**31。如果您使用模数 2**7 - 1 执行此操作,那么您将采用 L = 2**52 * 2**7。正如 djb 所说,这个技巧主要取决于中间结果不是以更高的精度计算。
【讨论】:
我想到的校验和只是将数字相加,并将结果模数作为素数。我对你的回答还是有点困惑。 X 是当前校验和,y 是我要添加的数字.. 都在整数范围 0...2**31 中。即使我有舍入,我如何实际计算模数?以上是关于获取特殊素数的浮点数模的快速、可向量化方法?的主要内容,如果未能解决你的问题,请参考以下文章