java - 高效的模 3 运算?

标签 java c++ c performance modulo

<分区>

Possible Duplicate:
Fast modulo 3 or division algorithm?

每个人都知道模运算可能会大大降低性能。有谁知道 x%3 操作的一个好的替代方案吗?我知道 x%2 存在一个,但我确实需要一个用于模 3,因为我想在 for 循环中的三个缓冲区之间交替。

谢谢!

最佳答案

好吧,而不是通常的“测量它”,而是实际的答案 - 因为这些东西实际上是真正有趣的数学。尽管编译器可以并且可能也这样做(至少现代优化的 c++ 编译器,javac 肯定不会,而且我不知道 JVM 是否这样做) - 所以最好检查它是否已经完成了工作你。

但了解优化背后的理论仍然很有趣:我将使用汇编,因为我们需要乘法的高 32 位字。以下内容摘自 Warren 关于位运算的书:

n 是我们想要取模的输入整数:

li M, 0x55555556   ; load magical number (2^32 + 2) / 3
mulhs q, M, n      ; q = higher word of M * n; i.e. q = floor(M*n / 2^32)
shri t, n, 31      ; add 1 to q if it is negative
add q, q, t

这里 q 包含 n/3 的除数,因此我们只需像往常一样计算余数:r = n - q*3

数学是有趣的部分—— latex 在这里会很酷:

q = 楼层( (2^32+2)/3 * (n/2^32) ) = 楼层( n/3 + 2*n/(3*2^32) )

现在对于 n = 2^31-1(带符号的 32 位整数可能的最大 n),误差项小于 1/3(并且非负),这使得很容易证明结果确实是正确的。对于 n = -2^31,我们在上面进行了 1 的修正,如果你简化它,你会发现误差项总是大于 -1/3,这意味着它也适用于负数。

我将带有错误项边界的证明留给感兴趣的人——这并不难。

关于java - 高效的模 3 运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8141802/

相关文章:

c++ - 不使用 cout、printf 或 puts() 打印内容

C 中 ffmpeg 的自定义实时输入

java - Jersey 在部署为 JAR 时找不到资源,但可以在 Eclipse 中使用

java - 有没有办法在两个不同的 jvm 上运行相同的 junit 测试

java - 需要代码优化建议

c++ - msys2 静态 QT undefined reference 问题

c++ - 在 visual studio 中为 usertype.dat 中的关键字赋值?

java - 颜色未设置到工作簿

c++ - 从函数返回 const 引用

c++ - 我可以有条件地替换预处理器参数吗?