首先,请原谅我,因为我的问题可能看起来很愚蠢,但我真的很好奇为什么我在这个非常简单的代码中获得了性能提升。

这是汇编代码:

__asm {
    mov eax, 0
    mov ecx, 0
    jmp startloop
    notequal:
    inc eax
    mov ecx, eax
    sub ecx, 2
    startloop:
    cmp eax, 2000000000
    jne notequal
};

这是 C 代码:
long x = 0;
long ii = 0;
for(; ii < 2000000000; ++ii)
{
    x = ii - 2;
};

在我的 i5 2500k 机器上完成 C 代码大约需要 1060 毫秒(在发布版本中),并且组装在 780 毫秒内完成。速度提高了约 25%。我不明白为什么我会得到这个结果,因为 25% 是一个很大的差异。编译器不够聪明,无法生成与我编写的相同的汇编代码吗?

顺便说一句,我正在使用 MSVC 2010。

谢谢

这是 MSVC 生成的(asm)代码
$LL3@main:
; Line 36
    lea esi, DWORD PTR [eax-2]
    inc eax
    cmp eax, 2000000000             ; 77359400H
    jl  SHORT $LL3@main

在这种情况下, lea 指令有什么作用?

更新 2

非常感谢大家。我刚刚在 Nehalem xeon cpu 上测试了这段代码,结果在这里是相同的。看起来不知什么原因,asm 代码在 Sandy 桥上运行得更快。

最佳答案

@modelnine 的评论是正确的 - lea 用于简化循环中的分配。你有:

x = ii - 2;
lea(加载有效地址)指令正在有效执行:
esi = &(*(eax - 2));
&* 相互抵消(这很重要 - 在这种情况下取​​消引用 eax 可能会导致问题),所以你得到:
esi = eax - 2;

正是您的 C 代码试图执行的操作。

10-08 16:29