结果为 0 但不会破坏依赖性的指令

Bon*_*ero 4 x86 assembly cpu-architecture microbenchmark

我开发了一个小基准。该基准测试中循环的结果应转换为零,并且下一轮计算应取决于之前循环的零“结果”来测量代码的延迟而不是其吞吐量。将结果移至另一个寄存器并对其本身进行异或运算是行不通的,因为当今的 CPU 认识到与其自身进行异或运算并不依赖于之前的指令。所以我尝试从寄存器本身中减去寄存器,希望CPU(Ryzen Threadripper 3990X)没有像XOR这样的快捷方式。我用一个单独的程序对此进行了评估:

#include <iostream>
#include <chrono>

using namespace std;
using namespace chrono;

int main()
{
    auto start = high_resolution_clock::now();
    for( size_t i = 1'000'000'000; i--; )
        __asm
        {
            sub     eax, eax
            sub     eax, eax
            sub     eax, eax
            sub     eax, eax
            sub     eax, eax
            sub     eax, eax
            sub     eax, eax
            sub     eax, eax
            sub     eax, eax
            sub     eax, eax
        }
    double ns = (int64_t)duration_cast<nanoseconds>( high_resolution_clock::now() - start ).count() / 10'000'000'000.0;
    cout << ns << endl;
}
Run Code Online (Sandbox Code Playgroud)

“不幸的是”CPU在这里也做了一个捷径,每条指令大约需要0.06ns,即。CPU 在每个时钟周期 (4,3GHz) 中执行大约 6 个 sub eax, eax。

那么有没有办法让一条指令的结果为零,并且该指令依赖于现代CPU上的之前的指令?

fuz*_*fuz 6

使用and立即数为零的 an。

and eax, 0
Run Code Online (Sandbox Code Playgroud)

这些指令xor eax, eaxsub eax, eax都被认为是归零习语,并且不会起作用。


归档时间:

查看次数:

115 次

最近记录:

3 年,10 月 前