Kay*_*Kay 6 x86 intel cpu-architecture cpu-cache amd-processor
Write-Combine缓冲区是如何物理连接的?我已经看到了说明许多变体的方框图:
它是依赖于微架构的吗?
写缓冲区可以在不同处理器中具有不同目的或不同用途.此答案可能不适用于未明确提及的处理器.我想强调术语"写缓冲区"在不同的上下文中可能意味着不同的东西.这个答案仅适用于Intel和AMD处理器.
每个缓存可能伴有零个或多个行填充缓冲区(也称为填充缓冲区).L2处的填充缓冲区的集合称为超级队列或超级队列(超级队列中的每个条目都是填充缓冲区).如果缓存在逻辑核心或物理核心之间共享,则相关的填充缓冲区也在核心之间共享.每个填充缓冲区可以包含一个缓存行和描述缓存行(如果它已被占用)的附加信息,包括缓存行的地址,内存类型和一组有效位,其中位数取决于粒度跟踪缓存行的各个字节.在早期的处理器(例如Pentium II)中,只有一个填充缓冲区能够进行写入组合(和写入折叠).使用较新的处理器,行缓冲器和能够写入梳理的总数稳步增加.最近的英特尔处理器在每个L1数据高速缓存中包含10个填充缓冲区,所有这些都可以组合写入(不要与特定的写入组合(WC)存储器类型混淆).制作一个能够进行写入梳理的填充缓冲区需要额外的硬件(不仅可以实现写入组合,还可以保持强排序存储器类型的存储顺序),因此这种功能不是免费的.
行填充缓冲区用于多种场景:
MOVNTDQA时L1D_PEND_MISS.FB_FULL,或序列化指令.填充缓冲区由高速缓存控制器管理,高速缓存控制器连接到其他级别的其他高速缓存控制器(或LLC的情况下的存储器控制器).当请求在缓存中命中时,不会分配填充缓冲区.因此,在高速缓存中直接执行在高速缓存中命中的存储请求,并且从高速缓存直接服务在高速缓存中命中的加载请求.当从缓存中逐出一行时,不分配填充缓冲区.被驱逐的行被写入自己的缓冲区(称为写回缓冲区或逐出缓冲区).以下是英特尔的一项专利,该专利讨论了针对I/O写入的写入梳理.
我已经运行的实验,这是非常相似的,我所描述的位置,以确定即使有多个负载在同一线路上的单一LFB是否被分配.事实证明确实如此.对回写L1D高速缓存中未命中的行的第一次加载获得为其分配的LFB.阻止所有后续加载到同一缓存行,并在其相应的加载缓冲区条目中写入块代码,以指示它们正在等待该LFB中保存的相同请求.当数据到达时,L1D高速缓存向加载缓冲区发送唤醒信号,并且当至少一个加载端口可用时,所有在该行上等待的条目被唤醒(未阻塞)并被调度发布到L1D高速缓存. .显然,内存调度程序必须在未阻塞的负载和刚刚从RS调度的负载之间进行选择.如果在所有等待负载得到服务机会之前,由于某种原因线路被驱逐,那么它们将再次被阻塞,并且将再次为该线路分配LFB.我没有测试商店的情况,但我认为无论操作是什么,都会为一条线分配一个LFB.LFB中的请求类型可以从预取到需求负载升级到推测RFO,以在需要时提供RFO.我还从经验中发现,在冲洗管道时,不会删除从错误预测路径上的uops发出的推测性请求.它们可能会降级为预取请求.我不确定.
我之前根据一篇文章提到过,有些AMD处理器使用的缓冲区与非临时存储区的填充缓冲区分开.我引述文章:
在较旧的AMD处理器(K8和系列10h)上,非临时存储使用一组四个"写入组合寄存器",它们独立于用于L1数据高速缓存未命中的八个缓冲区.
"老款AMD处理器"部分让我很好奇.这是在新款AMD处理器上有所改变吗?在我看来,在包括最新的17h系列处理器(Zen)在内的所有新款AMD处理器上都是如此.关于Zen mircoarchitecture 的WikiChip 文章包括两个提到WC缓冲区的数字:这个和这个.在第一个图中,不清楚如何使用WCB.但是,在第二个中,显然所示的WCB确实专门用于NT写入(WCB和L1数据高速缓存之间没有连接).第二个数字的来源似乎是这些幻灯片1.我认为第一个数字是由WikiChip制作的(这解释了为什么WCB处于不确定的位置).事实上,WikiChip的文章没有说明WCB的任何内容.但尽管如此,我们可以确认出仅用于NT的WCBS通过查看图7从编写软件优化指南AMD系列处理器17小时手册和专利的加载和存储队列家庭17H处理器.AMD优化手册指出现代AMD处理器中每个核心有4个WCB.我认为这适用于K8和所有后来的处理器.不幸的是,没有任何关于扮演英特尔填充缓冲区角色的AMD缓冲区的说法.
(1)迈克尔克拉克,2016年AMD高性能x86核心设计.
在现代Intel CPU中,写入组合由LFB(行填充缓冲区)完成,也用于来自L1 < - > L2的其他未决传输.每个核心都有10个(自Nehalem以来).(L2和L3之间的传输使用不同的缓冲区,称为"超级队列").
这就是为什么英特尔建议在进行NT存储时避免过多的其他流量,以避免因分配LFB的需求负载导致部分填充的LFB的早期冲洗. https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers
LFB的"内部"具有到L1d,存储缓冲区和加载端口的连接.
LFB的"外部"可以与L2通信或(可能在L2的帮助下)通过环形总线/网格到内存控制器,或L3用于NT预取.对于L3和内存来说,离开核心可能并没有太大的不同; 只是在核心之间的环/网状互连上发送不同类型的消息; 在英特尔CPU中,内存控制器只是环形总线上的另一个停靠点(在"系统代理"中),就像其他核心的L3一样. @ BobOnRope建议 L1 LFB并不真正直接连接到环形总线,并且那些不将数据放入L2的请求可能仍然通过L2超级缓冲区到达环形总线/网格.这似乎很可能,因此每个核心只需要在环形总线上存在一个点并在L2和L1之间进行仲裁发生在核心内部.
NT存储数据直接从存储缓冲区进入LFB,并且探测L1d以查看它是否需要首先驱逐该行.
当正常存储数据从L1d逐出时,正常存储数据进入LFB,或者为分配新线路或者响应来自想要读取该线路的另一个核心的RFO腾出空间.
在L1d中丢失的正常负载(和存储)需要高速缓存来获取该行,该行还分配LFB以跟踪进入的线路(以及对L2的请求).当数据到达时,它会直接发送到等待它的加载缓冲区,与将其放入L1d并行.(在CPU体系结构术语中,请参阅"早期重启"和"关键字优先":缓存未命中仅阻塞,直到所需数据到达,其余的缓存行"在后台"到达.)您(以及CPU架构师在英特尔)绝对不希望L2命中延迟包括将数据放入L1d并再次将其恢复.
来自WC内存(movntdqa)的NT加载直接从LFB读取 ; 数据永远不会进入缓存.LFB已经连接到加载端口以便提前重启正常负载,因此movntdqa我认为SSE4能够在没有大量额外成本的情况下添加.特别之处在于,未命中只会直接从内存中填充LFB,绕过L3/L2/L1.NT商店已经需要LFB才能与内存控制器通信.
L1 缓存中有许多缓冲区。
该专利提供了以下缓冲区类型:
该专利建议这些都可以是同一个物理缓冲区的功能,或者它们可以在物理上分开并且每个功能都有一组缓冲区。在 Intel 上,Skylake 上的 12 个 LFB 可能是全部,并且逻辑功能在它们之间通过类型或状态字段共享。在一些实施例中,行填充缓冲器还可以处理USWC加载/存储。在一些实施例中,专用缓冲区可以处理未命中 L1 的可缓存的非临时 (NT) 加载/存储(这样它们不会“填充”L1d 缓存,就像顾名思义,利用 NT 提示来防止缓存污染) .
此处的“写入组合缓冲区”意味着 USWC 内存/非时间性和固有的弱排序和不可缓存性,但实际的“写入组合”一词并不意味着这些事情中的任何一个,并且它本身可能只是一个概念,其中常规写入未命中相同的存储缓冲区被压缩并按程序顺序写入相同的行填充缓冲区。一项专利提出了此类功能,因此未标记为 WC 的常规临时写入缓冲区很可能具有组合功能。相关:写组合缓冲区是否用于对英特尔 WB 内存区域的正常写入?
x86-64 优化手册指出(大量赠品):
在对一级缓存的写入未命中时,它允许在从缓存/内存层次结构中更远的地方读取该缓存线以获取所有权 (RFO) 之前,对同一缓存线进行多次存储。然后读取行的其余部分,将未写入的字节与返回行中未修改的字节组合。存储排序和可见性也是写入组合的重要问题。当发生对先前未写入的缓存行的写入组合缓冲区的写入时,将发生所有权读取 (RFO)。如果后续写入发生在另一个写入组合缓冲区,则可能会导致该缓存行出现单独的 RFO。对第一个缓存行和写入组合缓冲区的后续写入将被延迟,直到第二个 RFO 已被服务以保证写入的正确排序可见性。
这是使用术语“写入组合缓冲区”来描述具有纯粹组合能力的常规写入缓冲区的明显证据,其中保持强排序。我们现在还知道,分配写入组合缓冲区的不仅仅是对任何内存的非临时存储,而是所有写入(因为非临时存储不发出 RFO)。缓冲区用于在 RFO 发生时组合写入,以便完成存储并释放存储缓冲区条目(如果它们都写入同一缓存行,则可能有多个)。无效位表示当缓存线到达 E 状态时要合并到缓存线中的位。一旦该行出现在缓存中,LFB 就可以转储到缓存中,然后所有写入该行的内容要么直接写入缓存行,
所以现在看起来,所有缓冲区都可以是任何类型的逻辑缓冲区,所有逻辑写缓冲区都是写组合缓冲区(除非是 UC),并且缓存类型决定了缓冲区在弱/强排序方面的处理方式以及 RFO执行或是否将其写回缓存。LFB 中的缓存类型来自 TLB(从 PMH 获取缓存类型,分析 PTE、PAT MSR 和 MTRR MSR 并计算最终缓存类型),或缓冲后的 SAB(存储地址缓冲区)推测性 TLB 查找的结果。
所以现在有 6 种类型的缓冲区:
这些缓冲区由物理地址索引,并与 L1 缓存并行扫描,如果它们包含有效数据,则可以更快、更有效地满足读/写命中,直到它们在解除分配条件发生时被解除分配。我认为“10 个 LFB”值是指可用于前两个目的的缓冲区数量。L1d 写回有一个单独的 FIFO 队列。
我们不要忘记缓存类型的优先顺序:
此处的 MTRR 包括默认类型,其中范围未由 MTRR 映射。MTRR 是由 MTRR 解决了任何冲突或默认值而产生的最终类型。首先,默认值被解析为 UC 并与任何 UC MTRR 排名相同,然后将任何冲突的 MTRR 组合成最终的 MTRR。然后将此 MTRR 与 PAT 和 E 位进行比较,具有最高优先级的成为最终的内存类型,尽管在某些情况下,它们是导致创建不同类型的非法组合。没有UC-MTRR。
缓存类型说明(时间):
缓存类型说明(非临时):
WB(请参阅完整讨论)。在某些实现中,在 L1 缓存中写入命中 可以使用强制 PLRU 将写入与 L1 中的行合并,以便它接下来被逐出(作为 WB),或者写入命中导致逐出,然后分配一个写入组合专用缓冲区,就像有未命中一样,这是写回 USWC(使用 WCiL(F)) 在解除分配条件下。写未命中分配一个专用的写组合缓冲区,并在释放时将其作为 USWC 写回内存,但如果该未命中导致 L2 命中,则写组合缓冲区会立即写入 L2 或在释放条件下写入,这将导致立即从 L2 逐出或强制 PLRU 位,因此它是下一个逐出。缓冲区继续满足对该行的进一步读/写,直到它被释放。NT 写入是弱排序的。未处于 M/E 状态的 L1/L2 中的写入命中可能仍会导致WiL使当前和其他套接字上的所有其他内核无效以获得 E 状态,否则,它只会使线路无效,当最终创建 USWC 存储时,LLC 检查当前或远程套接字上是否有任何其他内核需要无效。如果完整的 USWC 存储(操作码WCiLF)命中 LLC 缓存,则 Cbo 将 IDI 无效(出于某种原因使 Cbo 发送的 IDI 操作码无效(作为 TOR 的 IPQ 逻辑队列中的出口请求的一部分)未记录)到所有内核带有副本,并且无论是否存在 LLC 未命中,都始终InvItoE根据 SAD 交织规则向正确的家乡代理发送 QPI。存储只能在过滤器中的所有内核都响应无效并且家乡代理也响应时发生;在他们做出响应后,CboWrPull_GO_I从 L2 发送数据(代表具有全局观察通知和无效缓存行的写拉取)并将数据发送到家庭。如果部分 USWC 商店WCiL在 LLC 缓存中命中,也会发生同样的情况,除非现在在 LLC 切片中修改了该行(SnpInv如果该行仅存在于一个核心中,则来自它发送的而不是无效的 - 我猜它确实这样做了并且不只是发送简单的无效数据,WCiL就像它对 ) 所做的那样WCiLF或一直在 LLC 中进行修改,Cbo 在为 USWC 存储执行写启用位写回之前对家乡代理执行WBMtoI/ 。PAT 对虚拟地址进行操作,因此可能会出现别名,即同一个物理页面可以有多个不同的缓存策略。据推测,WP 写和 UC 读/写别名也具有相同的行为,但我不确定。WbMtoIPtlWcWrPtl
核心超队列是 L2 和 L3 之间的接口。SQ 也称为“非核心请求缓冲区”,任何非核心请求都称为已到达 SQ 的任何请求。虽然,我相信条目是为在 L1 写回中填充 L2 而分配的,这并不是真正的“请求”。因此可以得出OFFCORE_REQUESTS_BUFFER.SQ_FULL当 L1D 回写挂起 FIFO 请求缓冲区已满时可能发生,这表明如果该缓冲区已满,则无法分配 SQ 中的另一个条目,表明同时在 SQ 和该缓冲区中分配条目。对于 LFB,在 L2 命中时,数据直接提供给 LFB,否则,如果分配一个 SQ 条目并在从两个 32B IDI 事务中提取的数据写入 SQ 时提供给 LFB。进一步的 L2 未命中可以击中 SQ 并被压缩到同一个条目 ( SQ_MISC.PROMOTION)。
RFO 意图从存储缓冲区开始,如果它在 M 或 E 状态下命中 L1d 缓存,则执行写入并结束 RFO。如果线路处于 I 状态,则分配一个 LFB 并且 RFO 传播到 L2,如果存在于 M 或 E 状态,则可以在那里满足(当 M 线被写回 L2 时,它变为 M 状态有关于 L3)。如果它是 I 状态/不存在,则在 SQ 中分配它,并且一个RFO或ItoM数据包传播到处理地址范围的相应 LLC 切片 Cbo。然后,Cbo 切片使用窥探过滤器使其他内核无效,这涉及向内核发送无效请求(或窥探无效(SnpInv),如果它只存在于一个内核中——它也会获取数据,因为 Cbo 不知道这是否被修改)。Cbo 一直等到它收到来自内核的无效确认(以及修改后的数据)。然后,Cbo 向发出请求的内核的 SQ 指示它现在具有独占访问权限。它可能会提前确认这一点,因为 Cbo 可能必须从内存控制器获取数据,因此它可以提前确认数据不存在于任何其他内核中。SQ 将此信息传播到 L1d 缓存,这会导致在 LFB 中设置全局观察位,并且高级存储现在可以退出 SAB/SDB 以释放其条目。当数据最终到达时,它被传播到 LFB,
如果 WB 线存在于 L1 中但处于 S 状态,则在写入该线之前,它可能会或可能不会分配 LFB 以合并存储。如果它在 L1 中无效/不存在,则为合并存储分配一个 LFB。然后,如果该线路在 L2 中但处于 S 状态,WiL则将数据包发送到 LLC 切片(它只需要使其他内核无效)。然后它通知请求内核的 SQ 现在可以将其转换为 E 状态。该信息被传播到 L1d 缓存,在 L1d 缓存中,现在可以在 LFB 资源约束地址的解除分配条件发生之前将 LFB 合并到缓存中。
ItoM当假定要写入整行时,使用 代替 RFO,因此它不需要行中已有数据的副本,并且如果数据处于任何其他状态(S, E、M)。理论上,StoI即 aWiL与 RFO 相同,E 相同,除了 I,其中ItoM和 RFO 的不同之处在于 LLC 不需要将数据发送到核心ItoM. 该名称仅强调状态更改。它如何知道整行将被我不知道的存储写入......也许 L1d 缓存可以在分配 LFB 时一次性压缩 MOB 中的一堆顺序高级存储,因为 RFO 会立即发送我想分配(然后在 RFO 到达后将它们全部退休)。我想在必须生成操作码之前,商店还有一些时间到达 LFB(L2 查找)。这也可能被rep stos.
我假设 RFO IDI 数据包不需要区分需求锁定 RFO、预取 RFO、需求常规 RFO(非预取),以对应至强 5500 核心事件,但可能出于优先级目的(优先需求流量超过预取) ),否则只有核心需要知道这个信息,这要么被编码在一个中,RFO要么有单独的未记录的操作码。PrefRFO由内核发送用于预取到 LLC。
L1i 表面上缺少填充缓冲区意味着填充缓冲区的主要好处是存储和组合存储的位置,并且可以更快地释放存储缓冲区条目。由于 L1i 不执行任何存储,因此这不是必需的。我原以为它仍然读取了 LFB,以便它可以在填充缓存时或之前提供未命中数据,但后续读取不会加快,因为我认为缓冲区是 PIPT 并且它们的标签与缓存并行扫描。读取 LFB 还会压缩读取以指向 LFB 并防止多次查找,并通过跟踪 LFB MSHR 中的当前未命中来防止缓存阻塞,因此很可能存在此功能。
| 归档时间: |
|
| 查看次数: |
1406 次 |
| 最近记录: |