x64 性能与 x86 的比较
x64 performance compared to x86
我用 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: %drn", t2-t1);
getchar();
}
我在win7 x64上为x86和x64编译了它。
由于某种原因,当我运行 x64 版本时,它在大约 3 秒
内完成运行但是当我尝试使用 x86 版本时,它花了 48 (!!) 秒。
我尝试了很多次,总是得到类似的结果。
什么可能导致这种差异?
查看/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 刻度
原因确实与SSE有关。 VS 中的 64 位发布版本默认生成 SSE2 指令,但您必须使用 /arch:SSE2
开关为 32 位构建显式启用它。执行此操作时,您将获得 32 位和 64 位构建的可比运行时间。
这里的许多可能性与x86与x64几乎没有关系。一个明显的可能性是大多数(所有?)编译器使用 SSE 作为浮点数,其中大多数编译器通常在 x86 模式下使用 8087 样式的指令。由于您的代码在浮点上很重,这可能会产生重大差异。
另一种可能性是,在x64的过程或重写过程中,他们注意到/修复了代码生成器中的一些问题,至少在某些情况下,这些问题可以生成更好的代码。
虽然它看起来不适用于这里,但一些代码也从 64 位模式下可用的寄存器大小和/或数量的增加中受益匪浅。
其中一部分肯定是SSE,但x64使用SSE模式有很大的原因:所有AMD64 CPU都需要有SSE2。另一部分也可能是增加的寄存器数量
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么比较运算符如此快速
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 比较字符数组
- 将模板化的类型与C++中的某些类/类型进行比较
- C++自定义比较函数
- 如何比较自定义类的std::变体
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- std::设置自定义比较器
- 布尔比较运算符是如何在C++中工作的
- C++将目录中的所有文件与::filesystem进行比较
- 为x86而非x64编译时出错
- shell排序中的交换和比较
- 如何在C++中比较两个char数组
- catch框架有没有办法比较流或文件
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 智能指针作为无序映射键,并通过引用进行比较
- x64 性能与 x86 的比较
- 在 x86 CPU 上进行比较和交换
- x86 程序集比较参数