弱 ISA 如何使用存储缓冲区解决 WAW 内存危险?

2024-01-03

现代 CPU 使用存储缓冲区来延迟提交到缓存直至报废,同时也避免了 WAR 和 WAWmemory危险。我想知道弱 ISA 如何使用存储缓冲区(否则不是 FIFO)解决 WAW 危险,从而允许 StoreStore 重新排序?他们是否插入了隐性障碍?

更具体地说,如果对同一内存地址的两次存储在弱 ISA 上按顺序退出,例如ARM/POWER,理论上他们可以提交缓存无序的,由于存储缓冲区不是 FIFO,因此打破了 WAW 依赖性。

根据维基百科 https://en.wikipedia.org/wiki/Memory_disambiguation#Avoiding_WAR_and_WAW_dependencies:

...存储指令(包括内存地址和存储数据)缓冲在存储队列中,直到到达退休点。当存储退役时,它将其值写入内存系统。这避免了 WAR 和 WAW 依赖问题...


我猜;我不熟悉任何现实世界设计的细节

即使存储缓冲区是一个完整的调度程序,可以“抓取”任何分级存储以提交到 L1d,我假设它会使用最旧的就绪第一订单。(就像指令/uop 调度程序,又名 RS 保留站。)

“就绪”意味着缓存行是独占的(修改或独占状态)。每个分级存储本身都已隐式准备好提交,因为根据定义,关联的存储指令已退出。

按顺序停用意味着存储有资格按程序顺序提交,因此您不能拥有暂时隐藏在最早的就绪优先调度中的旧存储。总之,这些东西将确保对于任何给定的字节,重叠它的存储都按照程序顺序从而保持缓存行中任何给定字节组的全局可见性顺序和最终值的一致性。

内存屏障的工作原理可能是像杂货店结账传送带上的分隔物一样隔离存储缓冲区,防止抓取经过它的商店,同时将商店提交到同一行的同一位置。

我们确实知道现实世界中的弱排序存储缓冲区,例如PowerPC RS64-III(按顺序执行)和 Alpha 21264(OoO 执行) https://stackoverflow.com/a/54225485/224132进行合并以帮助他们创建对 L1d 的完整 4 字节或 8 字节对齐提交,例如从多个字节存储中。这也很好,假设您的合并算法尊重任何给定字节的顺序,例如通过将来自较新存储的数据放入较旧的 SB 条目中,反之亦然,并将另一个条目标记为“已提交”。显然,这必须尊重商店壁垒。

我认为即使对于未对齐的存储,这也很好,尽管保留未对齐存储的原子性保证在合并时可能会很棘手。 (Intel P6 系列及更高版本确实为不跨越缓存行边界的未对齐缓存存储提供原子性保证,但我们认为 Intel 不会正确合并存储缓冲区;也许只是一些用于缓存的 LFB 的东西 -错过同一条线上的连续商店。)

实际硬件可能不是可以合并任何 2 个 SB 条目的完整调度程序,例如也许只能在有限的范围内减少同时比较的不同地址(和大小)的数量。另外,您可能仍然只按程序顺序释放 SB 条目,因此它基本上可以是一个循环缓冲区(与 RS 不同)。按程序顺序进行分配,并通过 SB 本身的布局来跟踪顺序,使得内存屏障的工作和跟踪最年轻的“毕业”存储的位置变得更加便宜。

免责声明:我不知道这是否正是真正的硬件的工作原理


可能的极端情况:未对齐的 4 字节存储[cache_line+63](跨 CL 边界分割),然后[cache_line+60](完全包含在较低的缓存行中)。如果旧的存储缓冲区条目无法立即提交,因为我们尚未拥有该条目next缓存行,但我们确实拥有cache_line,我们还是不能让年轻的店cache_line+60如果我们依赖于没有发生的事情来避免 WAW 危险,请首先提交。

因此,您可能希望行分割 SB 条目能够将数据提交到一行,但不能提交到另一行,从而允许每个位置分别发生最旧的就绪优先,而不是将 2 个缓存行的顺序捆绑在一起。


相关:我写的我自己的答案 https://stackoverflow.com/questions/64141366/can-a-speculatively-executed-cpu-branch-contain-opcodes-that-access-ram解释什么是存储缓冲区。我试图避免像维基百科那样的错误(“when存储退休后,它将其值写入内存系统”:事实上,退休只是使其有资格提交;此类存储称为“分级”存储。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

弱 ISA 如何使用存储缓冲区解决 WAW 内存危险? 的相关文章

随机推荐