写合并缓冲区位于哪里?x86

15

写合并缓冲区是如何物理连接的?我看过一些块图,说明了一些变体:

  • 在L1缓存和内存控制器之间
  • 在CPU的存储缓存和内存控制器之间
  • 在CPU的AGU和/或存储单元之间

它是否与微架构有关?


1
在英特尔CPU中,LFB(线填充缓冲区)用于L1 <-> L2之间的其他挂起传输。这就是为什么英特尔建议在进行NT存储时避免过多的其他流量,以避免部分填充的LFB提前刷新。https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers - Peter Cordes
1
你真是无处不在的,Peter :) 感谢你提到 line-fill-buffers,这是我第一次听说它们。 - Kay
3个回答

27
写缓冲可以在不同的处理器中有不同的目的或用途。本答案可能不适用于未特别提到的处理器。我想强调,在不同的上下文中,“写缓冲”一词可能意味着不同的事情。本答案仅涉及英特尔和AMD处理器。
英特尔处理器上的写组合缓冲
每个高速缓存可能会配有零个或多个行填充缓冲区(也称为填充缓冲区)。L2 中的填充缓冲区集合称为超级队列或超队列(超级队列中的每个条目都是一个填充缓冲区)。如果缓存在逻辑核心或物理核心之间共享,则相关的填充缓冲区也在核心之间共享。每个填充缓冲区可以容纳一个缓存行和描述缓存行的其他信息(如果它被占用),包括缓存行的地址、内存类型和一组有效性位,其中位数取决于跟踪缓存行各个字节的粒度。在早期的处理器(如Pentium II)中,只有一个填充缓冲区能够进行写组合(和写折叠)。随着新处理器的推出,总线缓冲区数量和能够进行写组合的数量不断增加。
Nehalem到Broadwell每个L1数据缓存包括10个填充缓冲区。Core和Core2每个物理核心有8个LFB。根据此处,Skylake有12个LFB。@BeeOnRope观察到Cannon Lake有20个LFB。我在手册中找不到明确说明所有这些微架构上LFB与WCB相同的陈述。然而,这位来自英特尔的人所写的文章说:请参阅Intel® 64和IA-32架构优化参考手册,了解特定处理器中填充缓冲区的数量;通常数量为8至10。请注意,有时也称其为“写组合缓冲区”,因为在一些旧处理器上只支持流式存储。我认为LFB一词最初是由英特尔与英特尔Core微架构一起引入的,其中所有8个LFB也是WCB。基本上,英特尔在那时偷偷地将WCB重命名为LFB,但从那时起就没有在他们的手册中澄清这一点。
同一引用还指出,在旧处理器上使用WCB术语,因为它们不支持流式加载。这可以解释为LFB也被流式加载请求(MOVNTDQA)所使用。然而,第12.10.3节表明,流式加载将目标行提取到称为流式加载缓冲区的缓冲区中,这些缓冲区显然与LFB / WCB在物理上不同。
以下情况下使用线填充缓冲区:
(1) 在缓存中的加载未命中(需求或预取)时分配填充缓冲区。如果没有可用的填充缓冲区,则加载请求会继续堆积在加载缓冲区中,这可能最终导致阻塞发出阶段。在加载请求的情况下,分配的填充缓冲区用于临时保留来自内存层次结构较低的请求行,直到它们可以写入缓存数据数组。但是,即使尚未将该行写入缓存数据数组,仍可以向目标寄存器提供所请求的缓存行的部分内容。根据Patrick Fay(Intel)的说法:
“如果您在PDF中搜索'fill buffer',则可以看到Line fill buffer(LFB)在L1D未命中后被分配。 LFB在所有数据都准备好写入L1D缓存之前保持数据以满足L1D未命中。”

(2) 在可缓存存储器上分配了一个填充缓冲区到L1缓存中,目标行不处于允许修改的一致性状态。我的理解是,对于可缓存存储器,只有RFO请求被保存在LFB中,但要存储的数据会等待在存储器缓冲区中,直到为其分配的LFB条目中获取目标行。这得到了英特尔优化手册第2.4.5.2节中以下陈述的支持:

L1 DCache可以在从分配到退役期间维护最多64个加载微操作。它可以在从分配到将存储值提交到缓存或在非临时存储的情况下写入线填充缓冲区(LFB)的36个存储操作。

这表明,如果目标行不在L1D中,则可缓存存储器不会提交到LFB。换句话说,在目标行写入LFB,然后在LFB中修改该行,或者在目标行写入L1D,然后在L1D中修改该行之前,存储必须在存储器缓冲区中等待。

(3) 在L1高速缓存中,无论该行是否在缓存或其一致性状态如何,都会为不可缓存的写组合存储器分配填充缓冲区。对于相同缓存行的WC存储可以合并和折叠(在程序顺序之前,同一位置的多次写入将使程序顺序中的最后一个存储覆盖先前存储),在单个LFB中进行。在当前分配给LFB的请求中,没有维护排序。因此,如果有两个WCB正在使用,则无论与程序顺序的存储顺序如何,都不能保证哪个将首先被驱逐。这就是为什么即使所有存储都按顺序退役提交,WC存储也可能变得无序全局可见的原因(尽管WC协议允许WC存储以无序方式提交)。此外,WCB不被监视,因此只有当它们到达内存控制器时才变得全局可见。更多信息请参见Intel手册V3的第11.3.1节。

一些AMD处理器使用与非临时存储的填充缓冲区分离的缓冲区。在实现WCB的第一代P6和P4中也有许多专用于WC内存类型(不能用于其他内存类型)的WCB缓冲区。在早期版本的P4中,有4个这样的缓冲区。对于支持超线程的P4版本,在启用超线程并且两个逻辑核心都在运行时,WCB会在两个逻辑核心之间静态分配。然而,现代Intel微架构竞争性地共享所有LFB,但我认为至少为每个逻辑核心保留一个可用的以防止饥饿。

(4) L1D_PEND_MISS.FB_FULL的文档表明UC存储器也分配在相同的LFB中(无论该行是否在高速缓存中或其一致性状态如何)。与可缓存存储不同,但类似于WC,UC存储器不会合并在LFB中。

(5) 我已经通过实验观察到来自INOUT指令的请求也分配在LFB中。更多信息,请参见:使用环形总线拓扑的英特尔CPU如何解码和处理端口I/O操作

附加信息:

填充缓冲区由高速缓存控制器管理,该控制器连接到其他层级的高速缓存控制器(或在LLC的情况下连接到内存控制器)。当请求命中高速缓存时,不会分配填充缓冲区。因此,在高速缓存中命中的存储请求直接在高速缓存中执行,而在高速缓存中命中的加载请求直接从高速缓存中服务。当一行被驱逐出高速缓存时,不会分配填充缓冲区。被驱逐的行被写入它们自己的缓冲区(称为写回缓冲区或驱逐缓冲区)。这是Intel的一项专利,讨论了用于I/O写入的写组合技术。
我进行了一个非常类似于我在这里描述的实验,以确定即使存在多个对同一行的加载,单个LFB也会被分配。结果证明确实如此。第一个未命中写回L1D缓存的行的加载将为其分配LFB。所有后续对同一缓存行的加载都将被阻塞,并在相应的加载缓冲区条目中编写块代码,指示它们正在等待在该LFB中保存的相同请求。当数据到达时,L1D缓存向加载缓冲区发送唤醒信号,并唤醒(解除阻止)等待该行的所有条目,计划在至少有一个加载端口可用时将它们发出到L1D缓存。显然,内存调度程序必须在已解除阻止的加载和刚刚从RS调度的加载之间进行选择。如果该行由于任何原因而被逐出,而等待的所有加载没有机会得到服务,则它们将再次被阻塞,并且将再次为该行分配LFB。我没有测试过存储情况,但我认为无论是什么操作,都会为一行分配单个LFB。 LFB中的请求类型可以在需要时从预取升级为需求加载,然后是推测性RFO,最后是需求RFO。我还通过经验发现,从误预测路径上的uops发出的推测性请求在刷新管道时不会被删除。它们可能会降级为预取请求。我不确定。

AMD处理器上的写组合缓冲区

我之前提到根据一篇文章,有些AMD处理器使用与非临时存储的填充缓冲区分离的缓冲区。引用该文章中的内容:

在旧版AMD处理器(K8和Family 10h)上,非临时存储使用一组四个“写结合寄存器”,这些寄存器独立于用于L1数据缓存未命中的八个缓冲区。

“在旧的AMD处理器上”这部分让我很好奇。新的AMD处理器是否有所改变?在我看来,所有新的AMD处理器,包括最近的Family 17h处理器(Zen),都是如此。WikiChip对Zen微架构的文章包括两个提到WC缓冲区的图:thisthis。在第一个图中,不清楚WCB的使用方式。然而,在第二个图中,可以明确地看出所示的WCB确实专门用于NT写入(WCB与L1数据缓存之间没有连接)。第二个图的来源似乎是这些幻灯片1。我认为第一个图是由WikiChip制作的(这解释了为什么WCB被放置在一个不确定的位置)。事实上,WikiChip文章并未提及任何关于WCB的内容。但仍然可以通过查看AMD Family 17h处理器的软件优化指南手册和负责Family 17h处理器的加载和存储队列的专利中的第7个图来确认所示的WCB仅用于NT写入。AMD优化手册指出,现代AMD处理器每个核心有4个WCB。我认为这适用于K8和所有后续处理器。不幸的是,关于扮演Intel填充缓冲区角色的AMD缓冲区没有提及。

1 迈克尔·克拉克,AMD的一种新型高性能x86核心设计, 2016年。


2
好的回答。值得注意的是,由于这是一个英特尔特定的问题,英特尔喜欢将其从L2到更高级别的缓存中填充缓冲区/队列称为“超级队列”。我认为他们在L2<->L3和L3<->内存路径上都使用这个术语,因为实际上L3和内存控制器在环形总线上处于同一层次结构水平(当然,在内存控制器本身还有更多的队列)。 - BeeOnRope
2
没错,超级队列可能会做更多的事情,但我的观点是,你将每个缓存级别都描述为具有填充缓冲区,虽然这对于通用描述可能是正确的,但英特尔专门将术语“线路填充缓冲区”**仅用于L1<->L2缓冲区。对于那些管理L2缺失和与环形缓冲区通信的排队/缓冲机制,他们在给它命名时称之为超级队列(如果他们真的给它起了一个名字)。 - BeeOnRope
1
这种区别很重要,因为当英特尔在优化手册中提到缓冲区时,您想确切地知道他们所说的是哪些缓冲区,尤其是在查看性能事件名称时。 "填充缓冲区"和"超级队列"都出现在事件名称中,在这些情况下,它们指的是通往内存路径的非常具体的部分,如上所述。这两个队列的大小也不同(通常分别为LFB和SQ的10和16),有时这很重要。 - BeeOnRope
@LewisKelsey 请看我的博客文章 https://hadibrais.wordpress.com/2019/02/26/the-significance-of-the-x86-sfence-instruction/,了解全局可观测性的更多信息。 - Hadi Brais
1
@Noah,该语句并非在谈论分组或合并存储,而是表示为任何类型的请求都会分配一个LFB以进行进一步处理。因此,作为资源,所有类型的请求都使用LFB。 - Hadi Brais
显示剩余8条评论

12

在现代英特尔CPU中,写合并是由LFB(线填充缓冲器)完成的,也用于其他从L1<->L2的未决传输。自Nehalem以来,每个核心都有10个这样的缓冲器。(L2和L3之间的传输使用不同的缓冲区,称为“超级队列”)。

这就是为什么英特尔建议在进行NT存储时避免过多的其他流量,以避免由需求加载分配LFBs引起的部分填充LFBs的早期刷新。https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers

LFB的“内部”与L1d、存储缓冲区和加载端口相连。

LFB的“外部”可以与L2通信,或者(可能需要L2的帮助)通过环形总线/网格连接到内存控制器或L3以进行NT预取。对于L3和内存,离核心是没有太大区别的;只是在核心之间的环形/网格互连上发送不同类型的消息;在英特尔CPU中,内存控制器只是环形总线上的另一个停靠点(在“系统代理”中),就像其他带有其L3切片的核心一样。@BeeOnRope建议 L1 LFB并没有真正直接连接到环形总线,而那些不将数据放入L2的请求可能仍然通过L2超级队列缓冲区传递到环形总线/网格。这似乎很有可能,因此每个核心只需要在环形总线上具有一个存在点,并且在L2和L1之间的仲裁在核心内部进行。


NT存储数据直接从存储缓冲区进入LFB,同时探测L1d以查看是否需要先清除该行。

普通存储数据在从L1d中驱逐出来时进入LFB,无论是为了为新分配的行腾出空间还是响应其他核心的RFO请求以读取该行。

普通加载(和存储)如果在L1d中未命中,则需要缓存获取该行数据,这也会分配一个LFB来跟踪传入的行(和向L2的请求)。当数据到达时,它会直接发送到等待数据的加载缓冲区中,并同时放置在L1d中。(在CPU架构术语中,请参见"早期重启"和"关键字优先":缓存未命中只会阻塞,直到所需数据到达,其余的缓存行会"在后台"到达。)您(以及英特尔的CPU架构师)绝对不希望L2命中延迟包括将数据放置在L1d中并再次取回。

NT从WC内存中加载(movntdqa),直接从LFB读取;数据根本不进入缓存。 LFB已经连接到用于早期重启正常加载的加载端口,因此SSE4能够在不需要额外硅成本的情况下添加movntdqa。它是特殊的,因为一次未命中只会直接从内存中填充一个LFB,绕过L3 / L2 / L1。但是,NT存储器已经需要LFB能够与内存控制器通信。

1
嗨,彼得。太棒了你的回答。如果我可以问一下,LFBs是用于负载和存储吗?根据数据进入LFB的方式,它决定了发送数据的方式?即允许NT存储数据:存储缓冲区-> LFB-> mem.controller。与普通存储:L1D-> L2。 - Kay
1
LFB的“外部”可能从不与内存控制器通信。它可能只是与由L2和超级队列支持的一些仲裁组件通信,或者直接与L2和超级队列通信。如果L2未命中,则请求将发送到超级队列,而LFB将一直等待,直到返回。对于NT负载(预取),该请求可能只是被标记为不同,因此不会放入L2(并且可以由L3以不同方式处理)。然后,当L3被探测时,超级队列保留请求,如果也未命中DRAM,则继续等待。 - BeeOnRope
这是一个很好的回答,但它只是开始谈论Line Fill Buffers,而OP问的是Write Combining缓冲区。它们之间可能应该建立某种联系。据我所知,在英特尔芯片的最后十年左右(至少自Sandy Bridge以来,也许更早),根本就没有WC缓冲区这样的东西。 WC缓冲区的功能已经完全被LFB所取代,LFB具有更广泛的功能,处理从L1向外的所有数据移动,包括常规加载和存储。 - BeeOnRope
@BeeOnRope:更新到“现代英特尔”,避免任何历史错误陈述,但我认为仍然意味着它涵盖了所有人关心的CPU(或者至少到 Nehalem,因为我提到了每个核心的10个LFB的介绍,比 Core2 有所提升)。此外,根据您早期评论的更新,LFB <->内存控制器通过L2缓冲区进行。这是有道理的;当然 L1d 可以使用 L2 的缓冲区和连接到网格,而不实际将数据放入 L2。我的精神模型过于简单化,太字面化“绕过 L2 ”,但现在您指出来我同意。 - Peter Cordes
更新了我的回答。 - Hadi Brais
显示剩余5条评论

6

L1缓存中有许多缓冲区。

该专利给出了以下缓冲区类型:

  • 嗅探缓冲区(服务于来自其他核心的M/E状态嗅探(读取/RFO))
  • 写回缓冲区(服务于从L1驱逐的M状态)
  • 行填充缓冲区(服务于可缓存的load/store L1 misses)
    • 读取缓冲区(服务于可缓存的临时load的L1读取缺失)
    • 写入缓冲区(服务于可缓存的临时store的L1写入缺失)
    • 写组合行填充缓冲区(不确定,似乎与该专利中的写组合专用缓冲区相同)
  • 专用缓冲区(服务于不可缓存的load/store并且是“专用”的目的是从内存中获取而不是L2(但仍通过L2传递请求),并且不填充缓存行)
    • 非写组合专用缓冲区(服务于UC load/store和WP store)
    • 写组合专用缓冲区(服务于USWC load/store)
该专利建议这些可以是同一个物理缓冲区的功能,或者它们可以是物理上分离的,并且每个功能都有一组缓冲区。在Intel上,Skylake上的12个LFB可能是全部存在的,逻辑功能在它们之间共享,具有类型或状态字段。在某些实施中,线路填充缓冲区还可以处理USWC负载/存储。在某些实施中,专用缓冲区可以处理可缓存的非暂态(NT)加载/存储,这些加载/存储未命中L1(因此它们不会“填充”L1d缓存,就像名称所示,利用NT提示来防止缓存污染)。
"写合并缓冲区"在这里意味着USWC内存/非时间性以及固有的弱排序和不可缓存性,但实际上"写合并"这个词并不意味着任何这些东西,它可能只是一个概念,其中常规写错过了相同的存储缓冲区,被压缩并按程序顺序写入同一行填充缓冲区。专利建议了这样的功能,因此正常的时间写缓冲区如果没有标记为WC,可能具有合并功能。相关:Intel是否将写合并缓冲区用于对WB内存区域的普通写入? x86-64优化手册指出(大赠品):
在一级缓存未命中时,允许多个存储操作在该缓存行被从更深层次的缓存/内存层次结构中读取所有权(RFO)之前发生。然后读取剩余的行,并将未写入的字节与返回行中未修改的字节组合。存储排序和可见性也是写合并的重要问题。当先前未写入的缓存行的写合并缓冲区发生写入时,将进行所有权读取(RFO)。如果随后发生对另一个写合并缓冲区的写入,则可能导致该缓存行的单独RFO。为了保证写入正确有序可见性,第一个缓存行和写合并缓冲区的后续写入将延迟,直到第二个RFO已被服务。如果写入的内存类型是写合并,则不会有RFO,因为该行未被缓存,也没有这样的延迟。
这是明确的证据表明术语“写组合缓冲区”被用来描述具有纯粹组合能力且保持强排序的常规写缓冲区。我们现在也知道,不仅非暂态存储器对任何内存分配写组合缓冲区,而是所有写操作(因为非暂态存储器不发出RFOs)。当RFO正在进行时,缓冲区用于合并写入,以便完成存储并释放存储器缓冲区条目(如果它们都写入同一高速缓存行,则可能多个条目)。无效位指示到达E状态时要合并到高速缓存行中的位。一旦该行存在于高速缓存中并且之后的所有写入该行都直接写入高速缓存行,LFB就可以立即转储到高速缓存中,或者它可以继续分配以加速进一步的读/写,直到发生解除分配条件(例如,需要将其用于其他目的或者RFO到达该行,表示需要将其写回该行)。
现在看起来,所有缓冲区都可以是任何类型的逻辑缓冲区,所有逻辑写缓冲区都是写组合缓冲区(除非UC),缓存类型决定了缓冲区在弱/强排序方面的处理方式,以及是否执行RFO或将其写回到缓存中。LFB中的缓存类型可以来自TLB(从PMH获取缓存类型,该分析PTE、PAT MSRs和MTRR MSRs并计算最终缓存类型),也可以来自SAB(存储地址缓冲区)在缓冲规范性TLB查找的结果之后。

现在有6种缓冲区:

  • 写组合LFB(WB写失效/预取)
  • 读LFB(从UC和USWC以外的任何地方读取失效/预取)
  • 写组合专用缓冲区(WP写入,WT写入失效,USWC读/写,NT读/写到除UC以外的任何地方)
  • 专用缓冲区(UC读/写)
  • 嗅探缓冲区
  • 驱逐写回缓冲区
这些缓冲区按物理地址索引,并与L1高速缓存并行扫描,如果它们包含有效数据,则可以更快、更有效地满足读/写命中,直到发生解除分配条件时被释放。我认为“10个LFBs”值是指用于前两个目的的可用缓冲区数量。对于L1d写回,有一个单独的FIFO队列。
别忘了缓存类型的优先顺序:
- UC(Intel E位) - USWC(PAT) - UC(MTRR) - UC(PAT) - USWC(MTRR)(如果与WP或WT(PAT/MTRR)结合使用:逻辑和或非法:默认为UC) - UC-(PAT) - WT WP(PAT/MTRR)(在此等级中组合MTRRs会导致内存类型的逻辑和;在此等级上将MTRR和PAT组合起来会导致逻辑和(Intel);AMD(非法:UC)) - WB(PAT/MTRR)

MTRR包括默认类型,其中MTRR未映射范围。 MTRR是通过解决任何冲突或默认值而产生的最终类型。首先,将默认值解析为UC并与任何UC MTRR具有相同的等级,然后将任何冲突的MTRR组合成一个最终的MTRR。然后将此MTRR与PAT和E位进行比较,并且具有最高优先级的那个成为最终的内存类型,尽管在某些情况下,它们是不合法的组合,会导致创建不同的类型。没有UC-MTRR。

缓存类型(时间)的描述:

  • UC(强制非缓存):不允许推测性读取和写合并,强制有序。
  • UC-(弱非缓存):与UC相同,但对于PAT来说,优先级较低。
  • USWC(非缓存推测写合并):允许推测和写合并,读写均不被缓存。读和写都变得对其他读和写弱有序。
  • WT(写穿透):读取是可缓存的,并像WB一样工作。命中L1缓存的WT写同时更新L1缓存和外部内存,而未命中L1缓存的WT写仅更新外部内存。允许推测性读取和写合并,强制有序。
  • WP(写保护):读取是可缓存的,并像WB一样工作。写入不被缓存,导致行被无效。允许推测性读取,强制有序。
  • WB(写回):一切都被允许,强制有序。

缓存类型描述(非临时性):

  • NT UC没有区别(UC优先)
  • NT USWC和USWC没有区别,我想
  • NT WT我认为这个行为与NT WB完全相同。看起来是这样的
  • NT WP我不确定WP是否仅覆盖写入提示还是读取提示。如果它不覆盖读取,则读取可能像NT WB一样进行,最有可能。
  • NT WB在答案顶部的专利中,NT读取可以命中L1缓存,并使用偏向LRU策略来减少污染(类似于强制集合的树PLRU指向该路径)。读取未命中的行为类似于USWC读取未命中,并分配了一个写组合专用缓冲区,并导致LLC或其他核心或插座中的任何别名行被写回到内存,然后从内存中读取该行,并且读取也是弱序的。对于现代英特尔CPU的NT WB读取,具体实现因情况而异-- NT提示可以完全被忽略,它的行为就像WB请参见完整讨论)。 L1缓存中的写入命中在某些实现中可以将写入与L1中的行合并,并强制PLRU以便下次将其驱逐(作为WB),或者写入命中会导致一个驱逐,然后分配一个写组合专用缓冲区,就像有一个未命中一样,这将在释放条件下使用WCiL(F)写回USWC。写入未命中会分配一个专用的写组合缓冲区,并在取消分配时将其写回内存为USWC,但如果该未命中导致L2命中,则写组合缓冲区将立即写入L2或在取消分配条件下写入L2,这要么导致从L2立即被驱逐,要么强制PLRU位以便它是下一个驱逐。对该行的进一步读取/写入将继续由缓冲区满足,直到取消分配为止。 NT写入是弱序的。 L1 / L2中没有M / E状态的写入命中仍可能导致WiL使当前和其他插座上的所有其他核心无效,以获得E状态,否则,它只会使该行无效,并且当最终进行USWC存储时,LLC会检查是否需要使当前或远程插座上的任何其他核心无效。
如果LLC缓存中存在一个完整的USWC存储(opcode WCiLF),则Cbo向所有具有副本的核心发送IDI无效(由于某种原因,Cbo发送的作为TOR IPQ逻辑队列中出站请求的一部分的invalidate IDI opcode未记录)并且始终发送QPI InvItoE,无论是否存在LLC缺失,根据SAD交错规则将其正确发送到主代理。只有在筛选器中的所有核心都响应了无效操作并且主代理也响应之后,才能进行存储;在它们响应之后,Cbo会从L2发送WrPull_GO_I(表示全局观察通知和使缓存行无效的写入拉取)中的数据,并将数据发送到主机。如果LLC缓存中存在部分USWC存储WCiL,则发生相同的情况,但是如果该行现在已在LLC片段中被修改(从SnpInv发送而不是仅在一个核心中存在的无效操作,我猜它确实会这样做,而不仅仅是像对于WCiLF那样发送普通的无效操作),或者一直在LLC中被修改,则Cbo在执行USWC存储的写使能位写回WcWrPtl之前,对主代理执行WBMtoI/WbMtoIPtl。PATs基于虚拟地址操作,因此可能会发生别名,即同一物理页面可以具有多个不同的缓存策略。据推测,WP写入和UC读/写别名也具有相同的行为,但我不确定。
核心超级队列是L2和L3之间的接口。SQ也被称为“离核请求缓冲区”,任何离核请求都被视为已到达SQ的请求。虽然我认为在进行L1写回时会分配条目以填充L2,但这并不是一个真正的“请求”。因此,当L1D写回挂起FIFO请求缓冲区已满时,可能会发生OFFCORE_REQUESTS_BUFFER.SQ_FULL,这表明如果该缓冲区已满,则不能分配SQ中的另一个条目,这表明条目同时分配在SQ和该缓冲区中。至于LFB,在L2命中时,数据直接提供给LFB,否则在未命中时,如果分配了SQ条目,则在从两个32B IDI事务获取的数据写入SQ时提供给LFB。进一步的L2未命中可能会命中SQ,并被压缩到相同的条目(SQ_MISC.PROMOTION)。

一个RFO意图从存储缓冲区开始,如果它在L1d高速缓存中命中M或E状态,则执行写入并结束RFO。如果该行处于I状态,则分配LFB,并将RFO传播到L2,在那里可以满足它,如果它以M或E状态存在(当M行被写回到L2时,它在L3方面成为M状态)。 如果它是I状态/不存在,则在SQ中进行分配,并将RFO或ItoM数据包传播到处理地址范围的相应LLC切片Cbo。然后,Cbo切片使用探测过滤器使其他核心无效,这涉及向核心发送无效请求(或SnpInv进行探测无效(如果它仅存在于一个核心中-因为Cbo不知道是否已修改数据,因此也会获取数据)。 Cbo等待直到它收到来自核心的无效化确认(以及数据如有修改)。Cbo然后向请求核心的SQ表示它现在具有独占访问权。由于Cbo可能必须从内存控制器中提取数据,因此它很可能早期确认,表明数据不存在于任何其他核心中。 SQ将此信息传播到L1d高速缓存,这导致在LFB中设置全局观察位,并且高级存储器现在可以从SAB / SDB中退出以释放其条目。当数据最终到达时,它被传播到LFB,其中它与无效位合并,然后根据该地址的解除分配条件或由于LFB资源限制将其写入高速缓存。

如果L1中存在一个WB行但处于S状态,则在写入该行之前,它可能会或可能不会分配LFB以合并存储。如果在L1中无效/不存在,则将分配LFB以合并存储。然后,如果该行存在于L2中但处于S状态,则向LLC片发送WiL数据包(仅需要使其他核心失效)。然后通知请求核心的SQ现在可以将其转换为E状态。此信息被传播到L1d缓存中,其中LFB现在可以合并到缓存中,以避免针对LFB资源约束的释放条件发生。

ItoM被用于替代RFO,当我们假设整行都将被写入时,它就不需要已经在行中的数据副本,如果在其他状态(S、E、M)下,它已经有了数据。理论上的StoIWiL与RFO相同,除了I外,所有状态都是一样的,在ItoM和RFO之间的区别在于LLC不需要向核心发送数据进行ItoM。这个名称强调了状态的变化。我不知道它如何知道整行将要被存储..也许L1d高速缓存可以一次性压缩一堆连续的老年存储器存储在MOB中,同时分配一个LFB,因为在分配后立即发送RFO(然后一旦RFO到达就全部退休)。我想这还有一些时间,使得存储器可以到达LFB(L2查找),然后才生成操作码。这也可能被rep stos使用

我假设RFO IDI数据包不需要区分需求锁定RFO、预取RFO、需求常规RFO(非预取)与Xeon 5500核心事件相对应,但出于优先级目的可能需要(将需求流量优先于预取),否则只有核心需要知道这些信息,这要么编码在中,要么存在单独的未记录操作码。 PrefRFO由核心发送以预取到LLC。

L1i明显缺少填充缓冲区,这意味着填充缓冲区的主要好处是提供一个位置来存储和合并存储,并使得存储缓冲区条目更快地释放。由于L1i不执行任何存储操作,因此这不是必需的。我认为它仍然具有读取LFBs的功能,以便在或之前填充缓存时提供未命中数据,但是后续读取不会加速,因为我认为缓冲区是PIPT类型的,它们的标记与缓存并行扫描。读取LFBs还将压缩读取指向LFB的内容,并防止多次查找,同时通过跟踪LFBs MSHRs中的当前未命中来防止缓存阻塞,因此高度可能存在这种功能。


根据这里进行的测试,我认为可以合并到LFB中的多个可缓存存储不会将RFO优化为ItoM(仍然看到高uncore_read流量)。 - Noah
@Noah 我认为 ItoM 可能只是用于 rep stos 的,但我不确定。 - Lewis Kelsey
ItoMrep movsb/stosb和NT存储使用。据我所知,它不用于任何临时存储(也就是不用于64字节的zmm存储或组合的ymm存储)。 - Noah
@Noah 是的,我打算在某个时候测试那些性能事件。 - Lewis Kelsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接