c++ - 将两个 uint8_ts 视为 uint16_t 效率较低

标签 c++ integer bignum

假设我创建了一个类,它的模板参数等于我想串成一个大整数的 uint8_t 数。

这样我就可以像这样创建一个巨大的整数:

SizedInt<1000> unspeakablyLargeNumber;  //A 1000 byte number

现在问题来了:我是不是通过使用 uint8_t 而不是使用更大的内置类型来降低速度。

例如:

SizedInt<2> num1;
uint16_t num2;

num1num2 速度相同,还是 num2 更快?

最佳答案

毫无疑问,使用 uint8_t[2] 而不是 uint16_t 会更慢。

以加法为例。为了使 uint8_t[2] 的速度达到 uint16_t 的速度,编译器必须弄清楚如何转换您的 add-with-carry 逻辑和融合将这些多条指令合并为一条更广泛的指令。我敢肯定,有些编译器有时能够进行此类优化,但在很多情况下,这种优化不太可能或不可能进行。

在某些架构上,这甚至适用于加载/存储,因为 uint8_t[2] 通常具有与 uint16_t 不同的对齐要求。

典型的 bignum 库,例如 GMP , 处理对架构方便的最大单词。在 x64 上,这意味着使用 uint64_t 数组而不是像 uint8_t 这样更小的数组。在现代微处理器上相加两个 64 位数字的速度相当快,事实上,它通常与相加两个 8 位数字的速度相同,更不用说通过小数数组传播进位位引入的数据依赖性了。这些数据依赖性意味着您通常每个时钟周期只能添加一个数组元素,因此您希望这些元素尽可能大。 (在硬件层面,有一些特殊技巧可以让进位位在整个 64 位操作中快速移动,但这些技巧在软件中不可用。)

如果您愿意,您始终可以使用模板特化来选择合适大小的基元来制作您想要的最节省空间的 bignum。否则,使用 uint64_t 数组更为典型。

如果可以选择,通常最好只使用 GMP。 GMP 的某些部分是用汇编语言编写的,以使 bignum 操作比其他方式快得多。

关于c++ - 将两个 uint8_ts 视为 uint16_t 效率较低,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38163621/

相关文章:

c++ - 使用类和命名空间差异/歧义

javascript - JavaScript 中处理大数(BigNum)的标准方案是什么?

c++ - 无法解决错误 : indirection requires pointer operand ('int' invalid)

c++ - 调用无参数失败的可变参数模板函数

Python3 int.__sizeof__() 产生语法错误

php - 如何删除整数的最后一位? (PHP)

python - 将小数输入转换为 int 时出错

c++ - 使用 mpfr 数组的替代方法

找到最有效的基数来存储大整数的算法

c++ - 将 FILE 句柄重定向到字符缓冲区