x86上存储到加载转发失败的成本是多少? [英] What are the costs of failed store-to-load forwarding on x86?
本文介绍了x86上存储到加载转发失败的成本是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在最近的x86体系结构上失败的存储到加载转发的成本是多少?
具体而言,由于加载部分与较早的存储重叠,或者较早的加载或存储跨越导致转发失败的某些对齐边界而失败的存储到加载转发。
当然会有延迟成本:它有多大?是否还有吞吐量成本,例如,失败的存储到加载转发是否使用其他加载和存储甚至其他非内存操作无法使用的额外资源?当存储的所有部分都来自存储缓冲区时,与存储缓冲区和L1混合的情况有什么不同吗?
推荐答案
这不是真正的完整答案,但仍有证据表明处罚是可见的。
MSVC 2022基准,编译器/std:c++latest
。
#include <chrono>
#include <iostream>
struct alignas(16) S
{
char* a;
int* b;
};
extern "C" void init_fused_copy_unfused(int n, S & s2, S & s1);
extern "C" void init_fused_copy_fused(int n, S & s2, S & s1);
extern "C" void init_unfused_copy_unfused(int n, S & s2, S & s1);
extern "C" void init_unfused_copy_fused(int n, S & s2, S & s1);
int main()
{
using namespace std::chrono;
S s1, s2;
constexpr int N = 1'000'000'000;
auto t1 = system_clock::now();
init_fused_copy_fused(N, s2, s1);
auto t2 = system_clock::now();
init_fused_copy_unfused(N, s2, s1);
auto t3 = system_clock::now();
init_unfused_copy_fused(N, s2, s1);
auto t4 = system_clock::now();
init_unfused_copy_unfused(N, s2, s1);
auto t5 = system_clock::now();
std::cout
<< "init fused copy fused " << duration_cast<duration<double>>(t2 - t1) << "
"
<< "init fused copy unfused " << duration_cast<duration<double>>(t3 - t2) << "
"
<< "init unfused copy fused " << duration_cast<duration<double>>(t4 - t3) << "
"
<< "init unfused copy unfused " << duration_cast<duration<double>>(t5 - t4) << "
";
}
.code
c db 0
i dd 0
s dq byte ptr [c], dword ptr [i]
ALIGN 16
init_fused_copy_fused PROC
movups xmm0,xmmword ptr [s]
movups xmmword ptr [r8],xmm0
movups xmm1,xmmword ptr [r8]
movups xmmword ptr [rdx], xmm1
dec ecx
jnz init_fused_copy_fused
ret
init_fused_copy_fused ENDP
ALIGN 16
init_unfused_copy_fused PROC
lea rax, byte ptr [c]
mov qword ptr[r8], rax
lea rax, dword ptr [i]
mov qword ptr[r8 + 8], rax
movups xmm1,xmmword ptr [r8]
movups xmmword ptr [rdx], xmm1
dec ecx
jnz init_unfused_copy_fused
ret
init_unfused_copy_fused ENDP
ALIGN 16
init_fused_copy_unfused PROC
movups xmm0,xmmword ptr [s]
movups xmmword ptr [r8],xmm0
mov rax, qword ptr[r8]
mov qword ptr[rdx], rax
mov rax, qword ptr[r8 + 8]
mov qword ptr[rdx +8], rax
dec ecx
jnz init_fused_copy_unfused
ret
init_fused_copy_unfused ENDP
ALIGN 16
init_unfused_copy_unfused PROC
lea rax, byte ptr [c]
mov qword ptr[r8], rax
lea rax, dword ptr [i]
mov qword ptr[r8 + 8], rax
mov rax, qword ptr[r8]
mov qword ptr[rdx], rax
mov rax, qword ptr[r8 + 8]
mov qword ptr[rdx +8], rax
dec ecx
jnz init_unfused_copy_unfused
ret
init_unfused_copy_unfused ENDP
END
init fused copy fused 0.664739s
init fused copy unfused 0.935631s
init unfused copy fused 4.34326s
init unfused copy unfused 1.02741s
CPU:Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz 2.21 GHz
我对结果的解释如下:
- 融合init,转发永远不会失败。融合副本和未融合副本之间的差异在基准误差范围内
- 未融合的init,融合后的副本导致转发失败,性能差异显著
这篇关于x86上存储到加载转发失败的成本是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文