写组合缓冲区一直是Intel CPU的功能,至少可以追溯到Pentium 4甚至更早。基本思想是这些高速缓存行大小的缓冲区将写操作收集到同一高速缓存行中,因此可以将它们作为一个单元进行处理。作为它们对软件性能的影响的一个示例,如果您不编写完整的缓存行,则可能会遇到reduced performance。
例如,在Intel 64 and IA-32 Architectures Optimization Reference Manual部分的“ 3.6.10写合并”中,以以下描述开始(添加了重点):
写合并(WC)通过两种方式提高性能:
•写 错过了一级缓存,它允许多个存储到同一个 在读取缓存行以获取所有权(RFO)之前发生的缓存行 从缓存/内存层次结构的更远处开始。然后其余的线 读取,未写入的字节与 返回行中未修改的字节。
•写合并允许 多次写入将被组合并进一步写入高速缓存中 层次结构为单位。这样可以节省端口和总线流量。节省交通 对于避免部分写入未缓存尤为重要 记忆。
有六个写合并缓冲区(在Pentium 4和Intel上 具有系列15编码的CPUID签名的Xeon处理器 编码3;有8个写合并缓冲区)。这些缓冲区中的两个 可能会写出更高的缓存级别,并释放出来以用于 其他写未命中。仅保证四个写合并缓冲区 可供同时使用。 写合并适用于 内存类型WC;它不适用于内存类型UC。
有六个 Intel Core Duo和Windows Server 2003的每个处理器内核中的写合并缓冲区 英特尔酷睿Solo处理器。基于英特尔酷睿的处理器 微体系结构在每个内核中具有八个写合并缓冲区。 从英特尔微体系结构代码名称Nehalem开始,共有10个 可用于写合并的缓冲区。
写入合并缓冲区 用于存储所有内存类型。他们特别 对于写入未缓存的内存非常重要...
我的问题是,在使用普通存储区(非临时存储区以外的任何其他存储区)时,写合并是否适用于WB内存区域(即您在用户程序中99.99%的时间使用的“普通”内存)您99.9%的时间都在使用的商店)。
上面的文字很难准确解释,因为自Core Duo时代以来没有更新过。您有说写梳理的部分“适用于WC存储器,但不适用于UC”,但是当然不包括所有其他类型,例如WB。后来,您发现“ [WC对于写入未缓存的内存特别重要”,这似乎与“不适用于UC部分”相矛盾。
现代英特尔芯片上用于正常存储到WB存储器的写合并缓冲区是否也存在?
答案 0 :(得分:3)
是的,LFB的写合并和合并属性支持除UC类型以外的所有内存类型。您可以使用以下程序通过实验观察它们的影响。它以两个参数作为输入:
STORE_COUNT
:要顺序执行的8字节存储的数量。INCREMENT
:连续商店之间的跨度。 INCREMENT
有4个不同的值特别有趣:
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
我建议以下设置:
sudo wrmsr -a 0x1A4 0xf
禁用所有硬件预取器。这样可以确保它们不会干扰实验(或干扰最小)。 L1D_PEND_MISS.FB_FULL
性能计数器使我们能够捕获有关写入组合对LFB可用性的影响的效果。在Intel Core和更高版本上受支持。描述如下:
请求需要FB(填充缓冲区)条目但出现的次数 没有可用的条目。请求包括 加载,存储或软件预取的可缓存/不可缓存需求 说明。
首先运行不带内循环的代码,并确保L1D_PEND_MISS.FB_FULL
为零,这意味着刷新循环对事件计数没有影响。
下图将STORE_COUNT
相对于L1D_PEND_MISS.FB_FULL
除以ITERATIONS
的总和。
我们可以观察到以下情况:
L1D_PEND_MISS.FB_FULL
对于任何数量的存储都为零。L1D_PEND_MISS.FB_FULL
大于零。您后来发现,“ [WC对于写给 未缓存的内存”,似乎与“不适用于UC部分”相矛盾。
WC和UC均被归类为不可固定。因此,您可以将这两个语句放在一起得出WC对于写入WC内存特别重要。