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上的之前的指令?
使用and立即数为零的 an。
and eax, 0
Run Code Online (Sandbox Code Playgroud)
这些指令xor eax, eax和sub eax, eax都被认为是归零习语,并且不会起作用。
| 归档时间: |
|
| 查看次数: |
115 次 |
| 最近记录: |