Bee*_*ope 5 performance x86 intel cpu-architecture
写合并缓冲区一直是Intel CPU的功能,至少可以追溯到Pentium 4甚至更早。基本思想是这些高速缓存行大小的缓冲区将写操作收集到同一高速缓存行中,因此可以将它们作为一个单元进行处理。作为它们对软件性能的影响的一个示例,如果您不编写完整的缓存行,则可能会遇到性能下降的情况。
例如,在《Intel 64和IA-32体系结构优化参考手册》中,“ 3.6.10写合并”部分以以下说明(加了重点)开头:
写合并(WC)通过两种方式提高性能:
•在对第一级缓存的写入未命中时,它允许在从缓存/内存层次结构的更深层读取所有权(RFO)之前对该同一个缓存行进行多个存储。然后读取剩余的行,将尚未写入的字节与返回行中的未修改字节合并。
•写合并允许将多个写组合在一起,并作为一个单元在高速缓存层次结构中进一步写出。这样可以节省端口和总线流量。节省流量对于避免部分写入未缓存的内存特别重要。
有六个写合并缓冲区(在奔腾4和Intel Xeon处理器上,CPUID签名的族编码为15,模型编码为3;有8个写合并缓冲区)。这些缓冲区中的两个可以写出更高的缓存级别,并释放出来以供其他写未命中。保证只有四个写合并缓冲区可同时使用。写合并适用于存储器类型WC;它不适用于内存类型UC。
Intel Core Duo和Intel Core Solo处理器的每个处理器内核中都有六个写合并缓冲区。基于英特尔酷睿微体系结构的处理器在每个内核中都有八个写合并缓冲区。从英特尔微体系结构代码名称Nehalem开始,有10个缓冲区可用于写合并。
写合并缓冲区用于所有存储器类型的存储。它们对于写入未缓存的内存特别重要...
我的问题是,在使用普通存储区(非临时存储区以外的其他存储区,即您所使用的存储区)时,写合并是否适用于WB内存区域(即您在用户程序中使用99.99%的时间的“普通”内存)正在使用99.99%的时间)。
上面的文字很难准确解释,因为自Core Duo时代以来没有更新过。您有说写梳理的部分“适用于WC存储器,但不适用于UC”,但是当然不包括所有其他类型,例如WB。后来,您发现“ [WC对于写入未缓存的内存特别重要”,这似乎与“不适用于UC部分”相矛盾。
那么,现代英特尔芯片上用于正常存储到WB存储器的写合并缓冲区是否有效?
是的,LFB 的写入组合和合并属性支持除 UC 类型之外的所有内存类型。您可以使用以下程序通过实验观察它们的影响。它需要两个参数作为输入:
STORE_COUNT:要顺序执行的 8 字节存储的数量。INCREMENT:连续商店之间的步幅。有 4 个不同的值INCREMENT特别有趣:
STORE_COUNT)。写入合并和合并都会生效。还有另一个参数 ,ITERATIONS用于多次重复相同的实验以进行可靠的测量。您可以将其保持在 1000。
%define ITERATIONS 1000
BITS 64
DEFAULT REL
section .bss
align 64
bufsrc: resb STORE_COUNT*64
section .text
global _start
_start:
mov ecx, ITERATIONS
.loop:
; Flush all the cache lines to make sure that it takes a substantial amount of time to fetch them.
lea rsi, [bufsrc]
mov edx, STORE_COUNT
.flush:
clflush [rsi]
sfence
lfence
add rsi, 64
sub edx, 1
jnz .flush
; This is the main loop where the stores are issued sequentially.
lea rsi, [bufsrc]
mov edx, STORE_COUNT
.inner:
mov [rsi], rdx
sfence ; Prevents potential combining in the store buffer.
add rsi, INCREMENT
sub edx, 1
jnz .inner
; Spend sometime doing nothing so that all the LFBs become free for the next iteration.
mov edx, 100000
.wait:
lfence
sub edx, 1
jnz .wait
sub ecx, 1
jnz .loop
; Exit.
xor edi,edi
mov eax,231
syscall
Run Code Online (Sandbox Code Playgroud)
我推荐以下设置:
sudo wrmsr -a 0x1A4 0xf。这确保它们不会干扰(或最小干扰)实验。在L1D_PEND_MISS.FB_FULL性能计数器使我们能够捕捉写的关于合并的效果如何影响LFBs的可用性。它在 Intel Core 及更高版本上受支持。描述如下:
请求需要 FB(填充缓冲区)条目但没有可用条目的次数。请求包括可缓存/不可缓存的请求,即加载、存储或软件预取指令。
首先在没有内循环的情况下运行代码并确保它L1D_PEND_MISS.FB_FULL为零,这意味着刷新循环对事件计数没有影响。
下图绘制STORE_COUNT了 totalL1D_PEND_MISS.FB_FULL除以ITERATIONS。
我们可以观察到以下几点:
L1D_PEND_MISS.FB_FULL对于任意数量的存储为零。L1D_PEND_MISS.FB_FULL当存储数大于10时大于零。后来你知道“[WC] 对于写入未缓存的内存特别重要”,似乎与“不适用于 UC 部分”相矛盾。
WC 和 UC 都被归类为不可缓存的。所以你可以把这两个语句放在一起推导出WC对于写入WC内存特别重要。
另请参阅:Write-Combining Buffer 位于何处?x86。