assembly - 使用 xor reg, reg 是否比 mov reg, 0 有优势?

标签 assembly x86 micro-optimization

有两种众所周知的方法可以在 x86 上将整数寄存器设置为零值。

要么

mov reg, 0

xor reg, reg

有人认为第二种变体更好,因为值 0 没有存储在代码中,并且可以节省生成的机器代码的几个字节。这绝对是好事 - 使用较少的指令缓存,有时可以实现更快的代码执行。许多编译器都会生成这样的代码。

然而,异或指令与更改同一寄存器的任何早期指令之间存在形式上的指令间依赖性。由于存在依赖性,后一条指令需要等待前一条指令完成,这可能会减少处理器单元的负载并损害性能。

add reg, 17
;do something else with reg here
xor reg, reg

很明显,无论寄存器初始值如何,异或的结果都将完全相同。但处理器能够识别这一点吗?

我在VC++7中尝试了以下测试:

const int Count = 10 * 1000 * 1000 * 1000;
int _tmain(int argc, _TCHAR* argv[])
{
    int i;
    DWORD start = GetTickCount();
    for( i = 0; i < Count ; i++ ) {
        __asm {
            mov eax, 10
            xor eax, eax
        };
    }
    DWORD diff = GetTickCount() - start;
    start = GetTickCount();
    for( i = 0; i < Count ; i++ ) {
        __asm {
            mov eax, 10
            mov eax, 0
        };
    }
    diff = GetTickCount() - start;
    return 0;
}

关闭优化后,两个循环花费的时间完全相同。这是否合理地证明处理器认识到不存在 xor reg, reg 的依赖性先前的说明mov eax, 0操作说明?有什么更好的测试来检查这一点?

最佳答案

给你一个实际的答案:

Intel 64 and IA-32 Architectures Optimization Reference Manual

第 3.5.1.7 节是您想要查看的地方。

简而言之,在某些情况下可能会首选 xor 或 mov。问题集中在依赖链和条件代码的保存上。

In processors based on Intel Core microarchitecture, a number of instructions can help clear execution dependency when software uses these instruction to clear register content to zero.

In contexts where the condition codes must be preserved, move 0 into the register instead.

关于assembly - 使用 xor reg, reg 是否比 mov reg, 0 有优势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1135679/

相关文章:

assembly - 用户按下按键后程序显示垃圾

c# - 为什么 DateTime.Now DateTime.UtcNow 如此缓慢/昂贵

assembly - 汇编程序和跳转指令(它是如何工作的)

assembly - 使用 ymm 寄存器作为 "memory-like"存储位置

c - 内存地址计算在 "Smashing The Stack For Fun And Profit"

c - malloc 是确定性的吗?

linux - GDB 可以更改正在运行的程序的汇编代码吗?

c - 如何在内联汇编中声明字符缓冲区?

c++ - 更快地转换为字符串

c++ - 返回与。指针