gpt4 book ai didi

c - Sandy Bridge 上的 32 字节存储转发

转载 作者:太空狗 更新时间:2023-10-29 17:04:16 27 4
gpt4 key购买 nike

在 Agner Fog 的优秀 microarchitecture.pdf (section 9.14)我读到:

Store forwarding works in the following cases: [...] When a write of 128 or 256 bits is followed by a read of the same size and the same address, aligned by 16.

另一方面,Intel的架构优化引用手册(2.2.5.2 Intel Sandy Bridge,L1 DCache)我看过

Stores cannot forward to loads in the following cases: [...] Any load that crosses a 16-byte boundary of a 32-byte store.

任何负载听起来也像 32 字节负载。我编写了以下简单代码来对此进行测试,似乎 32 字节存储转发到 Sandy Bridge 架构上的后续 32 字节负载.这是代码:

#include <stdlib.h>
#include <malloc.h>

int main(){

long i;

// aligned memory address
double *tempa = (double*)memalign(4096, sizeof(double)*4);
for(i=0; i<4; i++) tempa[i] = 1.0;

for(i=0; i<1000000000; i++){ // 1e9 iterations

#ifdef TEST_AVX
__asm__("vmovapd %%ymm12, (%0)\n\t"
"vmovapd (%0), %%ymm12\n\t"
:
:"r"(tempa));
#else
__asm__("movapd %%xmm12, (%0)\n\t"
"movapd (%0), %%xmm12\n\t"
:
:"r"(tempa));
#endif
}
}

循环中唯一完成的事情是从/写入 4k 对齐的内存位置和 vector 寄存器。当使用 AVX 指令集 (gcc -O3 -DTEST_AVX) 编译时,在我的 2.7GHz i7-2620M 上执行时间为 3.1s。使用SSE2指令集时,时间为2.5s。我看过性能计数器。在 AVX 案例中,我每次迭代计算一个存储转发 block 事件(计数器 03H 02H LD_BLOCKS.STORE_FORWARD)。对于 SSE2 情况,计数器读数为 0。

任何人都可以阐明这一点吗? SB 确实不支持将 32 字节存储转发到 32 字节加载吗?如果是后者,溢出 ymm 寄存器似乎是一件相当昂贵的事情..

最佳答案

毕竟在 Sandy Bridge 上似乎没有 32 字节加载的存储到加载阻塞。考虑以下修改后的循环体:

#ifdef TEST_AVX
__asm__("vmovapd %%ymm12, (%0)\n\t"
"vmovapd (%0), %%ymm13\n\t"
:
:"r"(tempa));
#else
__asm__("movapd %%xmm12, (%0)\n\t"
"movapd (%0), %%xmm13\n\t"
:
:"r"(tempa));
#endif

变化是目标寄存器——我现在使用两个不同的寄存器来加载和存储,这样两条指令和后续迭代之间就没有依赖关系了。在这种情况下,SSE 版本每次迭代需要 1 个周期,而 AVX 版本需要 2 个周期。这与 SB 具有每个周期两个 16 字节加载的容量这一事实是一致的。因此,加载 32 字节需要两个周期 - 没有停顿。

问题一定与计数器逻辑有关。显然,在 AVX 情况下,LD_BLOCKS.STORE_FORWARD 递增,尽管没有发生阻塞。在使用计数器分析性能时应考虑到这一点。

关于c - Sandy Bridge 上的 32 字节存储转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22146956/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com