【问题标题】:x64 performance compared to x86x64 性能与 x86 相比
【发布时间】:2012-05-06 06:31:01
【问题描述】:

我用 C++ 编写了这个小程序来检查 CPU 负载情况。

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
int main()
{

    double x = 1;
    int t1 = GetTickCount();
    srand(10000);

    for (unsigned long i = 0; i < 10000000; i++)
    {
        int r = rand();
        double l = sqrt((double)r);
        x *= log(l/3) * pow(x, r);
    }

    int t2 = GetTickCount();
    printf("Time: %d\r\n", t2-t1);
    getchar();
}

我在 win7 x64 上为 x86 和 x64 编译了它。
出于某种原因,当我运行 x64 版本时,它在大约 3 秒内完成了运行
但是当我尝试使用 x86 版本时,它花了 48 (!!!) 秒。
我尝试了很多次,总是得到相似的结果。
什么可能导致这种差异?

【问题讨论】:

  • 什么编译器?以及哪些优化?
  • 我可能还会在最后打印 x,以确保优化器不会决定它可以丢弃 x *= 计算行。
  • 我正在使用带有“Microsoft Visual C++ 2010 Service Pack 1:Windows SDK 7.1 的编译器更新”的 vs2010 express。我在调试模式下编译它,没有进行任何优化。
  • 您确定在这两种情况下都使用了 Release 版本吗?
  • 当你在没有优化的调试模式下编译时,你已经告诉编译器你对代码的性能不感兴趣。那为什么要测量呢?

标签: c++ performance windows-7 x86 64-bit


【解决方案1】:

查看带有/Ox(最大优化)的汇编输出,x86 和 x64 构建的速度差异很明显:

; cl /Ox /Fa tick.cpp
; x86 Line 17: x *= log(l/3) * pow(x, r)
fld     QWORD PTR _x$[esp+32]
mov     eax, esi
test    esi, esi
; ...

我们看到 x87 指令正在用于此计算。将此与 x64 构建进行比较:

; cl /Ox /Fa tick.cpp
; x64 Line 17: x *= log(l/3) * pow(x, r)
movapd  xmm1, xmm8
mov     ecx, ebx
movapd  xmm5, xmm0
test    ebx, ebx
; ...

现在我们看到使用了 SSE 指令。

您可以通过/arch:SSE2 尝试并按摩 Visual Studio 2010 以生成类似的指令,但看起来 64 位编译器只是为您的任务生成更好更快的汇编就在眼前。

最后,如果您放宽浮点模型,x86 和 x64 的性能几乎相同。

时间安排,不科学的最佳 3:

  • x86, /Ox: 22704 滴答声
  • x64, /Ox: 822 滴答声
  • x86, /Ox /arch:SSE2: 3432 滴答声
  • x64, /Ox /favor:INTEL64: 1014 滴答声
  • x86, /Ox /arch:SSE2 /fp:fast: 834 滴答声

【讨论】:

    【解决方案2】:

    原因确实和SSE有关。 VS 中的 64 位版本默认生成 SSE2 指令,但您必须使用 /arch:SSE2 开关为 32 位版本显式启用它。当您这样做时,您将获得可比较的 32 位和 64 位构建的运行时间。

    【讨论】:

      【解决方案3】:

      这里的许多可能性与 x86 与 x64 几乎没有关系。一种明显的可能性是大多数(全部?)编译器使用 SSE 进行浮点运算,其中大多数通常在 x86 模式下使用 8087 样式的指令。由于您的代码大量使用浮点,这可能会产生重大影响。

      另一种可能性是,在为 x64 编写或重写的过程中,他们注意到/修复了代码生成器中的一些问题,使其能够生成更好的代码,至少在某些情况下是这样。

      虽然它看起来不适用于这里,但某些代码也可以从 64 位模式下增加的大小和/或数量的寄存器中受益匪浅。

      【讨论】:

        【解决方案4】:

        其中一部分肯定是 SSE,但 x64 使用 SSE 模式的一个重要原因是:所有 AMD64 CPU 都必须具有 SSE2。另一部分也可能是增加的寄存器数量

        【讨论】:

        • 暂时撇开浮点,这已经被其他海报所覆盖,增加了整数标量通用寄存器的寄存器集,将 r8 r9 等添加到 rax rbx 等对寄存器压力有很大帮助以前是在杀死程序员。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-17
        • 2013-02-18
        • 1970-01-01
        • 2011-08-24
        • 2021-12-19
        相关资源
        最近更新 更多