自定义按位与本机 CPU 操作的性能

Posted

技术标签:

【中文标题】自定义按位与本机 CPU 操作的性能【英文标题】:Performance of custom bitwise vs native CPU operations 【发布时间】:2021-10-29 04:06:20 【问题描述】:

大家!我一直在尝试为 C++ 中的 RSA 实现创建自己的大整数类(仅用于练习目的)。我认为在性能方面可以很好地实现这种东西的唯一方法是使用 C++ 的内置按位运算 (&|^),这意味着实现自定义全加器进行加法、二进制乘法器进行乘法等。我感兴趣的事情可以表述如下:使用按位 C++ 操作进行数字算术(如全加器、乘法器)的硬件电路的定制仿真器在性能方面会更慢。换句话说,如果我制作自己的 64 位大小的无符号整数类,并使其在执行加法、乘法、除法所需的按位运算数量方面“理想”,它能否具有与内置的 unsigned long long? 是否可以使用任何编程语言实现如此快的速度,或者您永远无法比 CPU 的内在指令集更快地执行任何操作? 请注意,我对有关 RSA 实现的答案不感兴趣,而只对本机和手工算术的性能比较感兴趣。 提前谢谢!

【问题讨论】:

完全取决于 CPU 的指令集,如果它有流操作。我认为你最好看看那些。例如,AVX-512 一次可以处理 512 位,这将超出正常操作。另请注意,内存/缓存性能可能会成为瓶颈。总而言之,我认为您无法超越 CPU 指令集。您的代码将始终更通用,因为它必须可编译用于超过 1 种类型的 CPU 【参考方案1】:

软件实现甚至无法接近硬件中通常使用的算术电路。这甚至不是基准测试或取决于系统的不同结果的问题(假设我们谈论的是不是史前的硬件),它是硬件电路的不二之选,每次都有很大的保证。硬件和软件之间的一个很大区别在于:硬件几乎具有无限的并行性,因此位操作的数量并不重要,速度主要取决于电路的“深度”。软件也有并行性,但非常有限。

考虑现代硬件中使用的典型快速乘法器。它们基于一些并行缩减方案,例如 Dadda 乘法器(实际电路不一定完全遵循 Dadda 的算法,但它会使用类似的并行缩减)。硬件具有几乎无限的并行性来进行并行减少。因此,64 位乘法在许多现代机器上需要 3 个周期(不是全部,但例如 Apple M1 和 all current Intel and AMD x64 processors)。诚然,在 3 个周期内,您可以压缩超过 3 个按位运算,但这甚至不是一场竞赛——您不能仅在少数几个按位运算中实现乘法。

即使只是添加也已经无与伦比。它已经和按位运算一样快,或者更准确地说,按位运算和加法一样慢。软件级别的按位运算所花费的时间与相应门的延迟几乎没有关系,它更多地是处理器总体设计方式的属性。顺便说一句,您可能也对这个问题感兴趣:Why is addition as fast as bit-wise operations in modern processors?

【讨论】:

【参考方案2】:

正如 P Kramer 在他的评论中所说,这完全取决于您的系统、指令集和编译器,现代编译器非常擅长在您要求时为您的特定 CPU 找到优化,但完全不可能知道它们是否仅通过理论,它的表现与本地指令一样好/更好。

在这种情况下,像往常一样,我建议进行 A/B 测试(如果使用 gcc/clang,请不要忘记使用 -march 和 -mtune)来检查哪个实现在您的机器上是最快的以及速度是多少。

【讨论】:

以上是关于自定义按位与本机 CPU 操作的性能的主要内容,如果未能解决你的问题,请参考以下文章

如何为自定义 CPU 创建 C 编译器?

Ubuntu下自定义调整CPU工作频率(用于省电或提高性能都好用)

java运算符

性能监控:jvm+cpu+目标field自定义类加载器+Java agent+反射实现对tomcat的零侵入式服务监控

python中的按位与 +按位或+ 按位反+异或运算 +左移+右移

性能监控:jvm+cpu+目标field自定义类加载器+Java agent+反射实现对tomcat的零侵入式服务监控