性能32位与64位算术

原生64 bit整数算术指令是否比其32 bit计数器部分慢(在64 bit OS的x86_64机器上)?

编辑:在目前的CPU如Intel Core2 Duo,i5 / i7等

这取决于确切的CPU和操作。 例如,在64位Pentium IV上,64位寄存器的乘法速度相当慢。 Core 2及更高版本的CPU从头开始设计用于64位操作。

通常,即使是为64位平台编写的代码也会使用32位变量,其中的值将适合它们。 这主要不是因为算术速度更快(在现代CPU上,通常不是),而是因为它使用较少的内存和内存带宽。

如果整数是32位,那么包含十几个整数的结构将是一半的大小,如果它们是64位的。 这意味着将需要一半的字节来存储,一半的缓存空间,等等。

当值可能不适合32位时,使用64位本地寄存器和算术。 但主要的性能优势来自x86_64指令集中可用的额外通用寄存器。 当然,所有的好处都来自64位的指针。

所以真正的答案是没关系。 即使你使用x86_64模式,你也可以(一般情况下)仍然使用32位算法,你可以从更大的指针和更通用的寄存器中获益。 当您使用64位本地操作时,这是因为您需要64位操作,并且您知道它们会比使用多个32位操作伪装更快 – 这是您唯一的选择。 所以32位和64位寄存器的相对性能决不应该是任何实现决策的决定性因素。

我只是偶然发现了这个问题,但是我认为在这里缺少一个非常重要的方面:如果真的看下使用'int'类型的汇编代码来索引可能会减慢编译器生成的代码。 这是因为'int'在许多64位编译器和平台(Visual Studio,GCC)上默认为32位类型,并且使用指针(在64位操作系统上必须是64位)进行地址计算,'int'会导致编译器放弃不必要的32位和64位寄存器之间的转换。 我刚刚在我的代码的一个非常性能严格的内部循环中体验到了这一点。 作为循环索引,从“int”切换到“long long”提高了我的算法运行时间约10%,考虑到当时我已经在使用的广泛的SSE / AVX2矢量化,这是相当巨大的收益。

在一个主要的32位应用程序(意味着只使用32位算术,32位指针就足够了),x86-64架构的真正好处是AMD对架构的其他“更新”:

  • 16个通用寄存器,在x86中为8个
  • RIP相对寻址模式
  • 其他…

这在Linux中实现的新的x32 ABI中很明显。