c - PC 上的蒙哥马利乘法与字长模数。这值得么?

标签 c word modular-arithmetic

我正在为一个数论研究项目编写一些 C 代码,该项目需要使用许多不同的模数进行大量模算术运算。简单来说:我需要多次执行 (a * b) % n 操作。

该代码旨在使用 64 位字在 PC 上运行,并且已知所有模数都小于 2^64,因此所有操作数均由无符号 64 位整数实现。

我的问题是:是否会使用蒙哥马利模乘法(仅使用加法和乘法)而不是 C 模运算符 %(转换为 a % n = a - n *(a/n) 并且还使用除法)导致执行速度更快?

直觉上,我会说答案是:不,因为 PC 上的(字大小)除法在计算上并不比(字大小)乘法昂贵太多,而且蒙哥马利缩减实际上会导致开销。

感谢任何建议。

更新:一方面,根据 Paul Ogilvie(请参阅下面的评论),(a * b) % n 需要 1 次乘法和 1 次除法。另一方面,蒙哥马利乘法需要(忽略将操作数转换和转换回蒙哥马利表示形式所需的操作,因为它们只对每个模 n 和二进制移位完成一次)3 次乘法。因此,一旦乘法比除法快两倍,蒙哥马利似乎就比“%”快...

最佳答案

你的直觉是错误的。除法比乘法慢很多倍,无论是整数还是 float 。参见 this excellent answer关于类似的问题。速度的确切差异取决于您在哪个 CPU 上运行,代码是否可以矢量化,甚至取决于代码的其余部分大约在同一时间在做什么。

如果你用一个常数除以整数,例如,如果你在编译时知道 n,那么编译器可以将其转换为一系列乘法和移位,甚至可能与蒙哥马利模乘法。如果 n 在编译时未知,那么实现蒙哥马利模乘法可能是值得的。

但是,当您实现代码的两个版本并对其进行基准测试时,您会得到最好的答案。

关于c - PC 上的蒙哥马利乘法与字长模数。这值得么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59823320/

相关文章:

c - 如何防止 execv 杀死我的程序?

c - 类型为 'int' 到 'int*' 到二进制 'operator*' 的无效操作数

java - 求模数的互质数

algorithm - 单词生成器算法?

C++代码在for循环的条件下给出运行时错误而如果它被具有相同意义的代码替换则编译正确

c - 如何使用使用 128 位二进制和 4 位多项式模的 C 编写模块化运算?

c - 当我运行 C 程序时,我的编译器返回 "assignment to ' int *' from incompatible pointer type ' char *' [-Wincompatible-pointer-types]"

c - 动态库加载 : easy way to figure out unresolved symbols runtime

C: 字符数组中的单词

linux - 如何在 Linux 中的文件中添加带有特定单词的新列?