弱 ISA 如何使用存储缓冲区解决 WAW 内存危险?
How do weak ISAs resolve WAW memory hazards using the store buffer?
现代 CPU 使用存储缓冲区来延迟提交到缓存中直到报废,这也避免了 WAR 和 WAW 内存 危险。我想知道弱 ISA 如何使用存储缓冲区解决 WAW 危害,否则它不是 FIFO,允许 StoreStore 重新排序?他们是否插入了隐性障碍?
更具体地说,如果两个存储到同一内存地址的顺序在弱 ISA 上退出,例如ARM/POWER,他们理论上可以提交缓存 乱序,因为存储缓冲区不是 FIFO,从而打破 WAW 依赖。
根据Wikipedia:
...the store instructions, including the memory address and store data, are buffered in a store queue until they reach the retirement point. When a store retires, it then writes its value to the memory system. This avoids the WAR and WAW dependence problems...
我的猜测;我不熟悉任何现实世界设计的细节
即使存储缓冲区是一个完整的调度程序,可以“抓取”任何分级存储以提交到 L1d,我假设它会使用最旧的第一个订单。(就像一个指令/uop 调度程序又名 RS 保留站。)
“就绪”意味着缓存行是独占的(已修改或独占状态)。每个分级存储本身都隐含地准备好提交,因为根据定义,关联的存储指令已经退休。
按顺序退役意味着商店有资格按程序顺序提交,因此您不能拥有暂时隐藏在最早就绪优先计划之外的旧商店。
总之,这些东西将确保对于任何给定的字节,与其重叠的存储按程序顺序排列,从而保持全局可见性顺序和高速缓存中任何给定字节组的最终值的一致性行。
内存屏障可能会像杂货店收银台传送带上的分隔线一样将商店缓冲区围起来,防止在将商店提交到同一行的同一位置时抢过它的商店。
我们确实知道像 这样的现实世界中的弱排序存储缓冲区会进行合并以帮助它们创建对 L1d 的整个 4 字节或 8 字节对齐的提交,例如出多个字节存储。这也很好,假设您的合并算法尊重任何给定字节的顺序,例如通过将数据从较新的商店放入较旧的 SB 条目,反之亦然,并将另一个条目标记为“已提交”。显然这必须尊重存储障碍。
我认为即使对于未对齐的存储,这一切都很好,尽管为未对齐的存储保留原子性保证在合并时可能会很棘手。 (英特尔 P6 系列及更高版本确实为不跨越缓存行边界的未对齐缓存存储提供原子性保证,但我们认为英特尔不会正确地合并存储缓冲区;也许只是一些带有用于缓存的 LFB 的东西-错过同一行的背靠背商店。)
很可能真正的硬件可能不是可以合并任何 2 个 SB 条目的完整调度程序,例如可能只是在有限的范围内,以减少一次比较的不同地址(和大小)的数量。此外,您可能仍然只按程序顺序释放 SB 条目,因此它基本上可以是一个循环缓冲区(与 RS 不同)。按程序顺序分配,并通过 SB 本身的布局跟踪顺序,使内存屏障的工作成本更低,并跟踪最年轻的“毕业”存储所在的位置。
免责声明:IDK 如果这正是真实硬件的工作方式
可能的极端情况:未对齐的 4 字节存储到 [cache_line+63]
(跨 CL 边界拆分)然后到 [cache_line+60]
(完全包含在较低的缓存行中)。如果旧的存储缓冲区条目不能立即提交,因为我们还没有拥有 next 缓存行,但我们拥有 cache_line
,我们仍然不能让年轻的商店 cache_line+60
先提交,如果我们依赖于没有发生的情况来避免 WAW 危害。
所以您可能希望分行的 SB 条目能够将数据提交到一行而不是另一行,从而允许每个位置分别发生最早就绪的优先顺序,而不是将顺序捆绑在一起2 个缓存行。
相关:我写了 解释什么是存储缓冲区。我试图避免像维基百科那样的错误(当 商店退休时,它会将其价值写入内存系统“:事实上退休只是让它有资格提交;这样的商店被称为“毕业”商店。)
现代 CPU 使用存储缓冲区来延迟提交到缓存中直到报废,这也避免了 WAR 和 WAW 内存 危险。我想知道弱 ISA 如何使用存储缓冲区解决 WAW 危害,否则它不是 FIFO,允许 StoreStore 重新排序?他们是否插入了隐性障碍?
更具体地说,如果两个存储到同一内存地址的顺序在弱 ISA 上退出,例如ARM/POWER,他们理论上可以提交缓存 乱序,因为存储缓冲区不是 FIFO,从而打破 WAW 依赖。
根据Wikipedia:
...the store instructions, including the memory address and store data, are buffered in a store queue until they reach the retirement point. When a store retires, it then writes its value to the memory system. This avoids the WAR and WAW dependence problems...
我的猜测;我不熟悉任何现实世界设计的细节
即使存储缓冲区是一个完整的调度程序,可以“抓取”任何分级存储以提交到 L1d,我假设它会使用最旧的第一个订单。(就像一个指令/uop 调度程序又名 RS 保留站。)
“就绪”意味着缓存行是独占的(已修改或独占状态)。每个分级存储本身都隐含地准备好提交,因为根据定义,关联的存储指令已经退休。
按顺序退役意味着商店有资格按程序顺序提交,因此您不能拥有暂时隐藏在最早就绪优先计划之外的旧商店。 总之,这些东西将确保对于任何给定的字节,与其重叠的存储按程序顺序排列,从而保持全局可见性顺序和高速缓存中任何给定字节组的最终值的一致性行。
内存屏障可能会像杂货店收银台传送带上的分隔线一样将商店缓冲区围起来,防止在将商店提交到同一行的同一位置时抢过它的商店。
我们确实知道像
我认为即使对于未对齐的存储,这一切都很好,尽管为未对齐的存储保留原子性保证在合并时可能会很棘手。 (英特尔 P6 系列及更高版本确实为不跨越缓存行边界的未对齐缓存存储提供原子性保证,但我们认为英特尔不会正确地合并存储缓冲区;也许只是一些带有用于缓存的 LFB 的东西-错过同一行的背靠背商店。)
很可能真正的硬件可能不是可以合并任何 2 个 SB 条目的完整调度程序,例如可能只是在有限的范围内,以减少一次比较的不同地址(和大小)的数量。此外,您可能仍然只按程序顺序释放 SB 条目,因此它基本上可以是一个循环缓冲区(与 RS 不同)。按程序顺序分配,并通过 SB 本身的布局跟踪顺序,使内存屏障的工作成本更低,并跟踪最年轻的“毕业”存储所在的位置。
免责声明:IDK 如果这正是真实硬件的工作方式
可能的极端情况:未对齐的 4 字节存储到 [cache_line+63]
(跨 CL 边界拆分)然后到 [cache_line+60]
(完全包含在较低的缓存行中)。如果旧的存储缓冲区条目不能立即提交,因为我们还没有拥有 next 缓存行,但我们拥有 cache_line
,我们仍然不能让年轻的商店 cache_line+60
先提交,如果我们依赖于没有发生的情况来避免 WAW 危害。
所以您可能希望分行的 SB 条目能够将数据提交到一行而不是另一行,从而允许每个位置分别发生最早就绪的优先顺序,而不是将顺序捆绑在一起2 个缓存行。
相关:我写了