Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将两个单元视为一个单元是否效率较低_C++_Integer_Bignum - Fatal编程技术网

C++ 将两个单元视为一个单元是否效率较低

C++ 将两个单元视为一个单元是否效率较低,c++,integer,bignum,C++,Integer,Bignum,假设我创建了一个类,该类的模板参数等于我要串成一个大整数的数字uint8\u ts 这样我可以创建一个巨大的int,如下所示: SizedInt<1000> unspeakablyLargeNumber; //A 1000 byte number num1和num2的速度是否相同,或者num2是否更快?由于循环开销减少,大型类型的性能可能会更好。然而,这里的折衷是速度更好,而选择尺寸的灵活性更低 例如,如果您的大多数数字长度为5字节,则切换到unit_16将需要额外的字节开销。这

假设我创建了一个类,该类的模板参数等于我要串成一个大整数的数字
uint8\u t
s

这样我可以创建一个巨大的int,如下所示:

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

num1
num2
的速度是否相同,或者
num2
是否更快?

由于循环开销减少,大型类型的性能可能会更好。然而,这里的折衷是速度更好,而选择尺寸的灵活性更低


例如,如果您的大多数数字长度为5字节,则切换到
unit_16
将需要额外的字节开销。这意味着20%的内存开销。另一方面,如果我们谈论的是非常大的数字,比如说50字节或更多,那么内存开销就会小得多——大约为2%,因此提高速度的成本就会小得多。

使用
uint8\u t[2]
而不是
uint16\u t
无疑会更慢

以加法为例。为了将
uint8\u t[2]
的速度提高到
uint16\u t
的速度,编译器必须弄清楚如何使用进位逻辑翻译加法,并将这些多条指令融合到一个更广泛的加法中。我确信有些编译器有时能够进行这样的优化,但是有很多情况可能使优化不太可能或不可能

在某些体系结构上,这甚至适用于加载/存储,因为
uint8\u t[2]
通常与
uint16\u t
具有不同的对齐要求

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

如果您愿意,您可以始终使用模板专门化来选择适当大小的基本体,以生成所需的最节省空间的bignum。否则,使用
uint64\t
的数组更为典型


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

我希望
num2
更快,因为它的操作可以在一条指令中完成,而
num1
将需要对其
uint8\t
成员进行至少两次操作。如果使用至少16位的处理器,则
num2
将更快,因为对于许多操作,将使用单CPU指令,而不是(据说更复杂的)
SizedInt
方法。但即使使用8位处理器,我怀疑这些方法的性能也会优于编译器生成的代码。
SizedInt<2> num1;
uint16_t num2;