存储指令是否会在缓存未命中时阻塞后续指令?

2023-11-22

假设我们有一个具有两个核心(C0 和 C1)的处理器和一个从地址开始的高速缓存行k最初由 C0 拥有。如果 C1 在第 8 行的 8 字节槽上发出存储指令k,这会影响 C1 上执行的以下指令的吞吐量吗?

intel优化手册有如下一段

当指令将数据写入内存位置 [...] 时,处理器确保包含该内存位置的行位于其 L1d 高速缓存 [...] 中。如果缓存行不存在,它将使用 RFO 请求 [...] RFO 从下一级获取数据,并在指令退出后存储数据。因此,存储延迟通常不会影响存储指令本身

参考下面的代码,

// core c0
foo();
line(k)->at(i)->store(kConstant, std::memory_order_release);
bar();
baz();

英特尔手册中的引用让我假设在上面的代码中,代码的执行看起来好像存储本质上是无操作,并且不会影响结束之间的延迟foo()和开始bar()。相反,对于以下代码,

// core c0
foo();
bar(line(k)->at(i)->load(std::memory_order_acquire));
baz();

结束之间的延迟foo()和开始bar()会受到负载的影响,因为以下代码将负载的结果作为依赖项。


这个问题主要与英特尔处理器(Broadwell 系列或更新版本)如何在上述情况下工作有关。另外,特别是关于如何将类似于上面的 C++ 代码编译为这些处理器的程序集。


一般来说,对于后续代码不会很快读取到的 store,该 store 不会directly延迟任何现代乱序处理器(包括英特尔)上的后续代码。

例如:

foo()
*x = y;
bar()

If foo()不修改x or y, and bar不加载自*x,商店是独立的,甚至可以在之前开始执行foo()已完成(或什至在开始之前),并且bar()可以在存储提交到缓存之前执行,并且bar()甚至可能执行 whilefoo()正在运行等

虽然有一点点direct影响,并不意味着没有间接影响,实际上存储可能会主导执行时间。

如果缓存中的存储未命中,则在满足缓存未命中的情况下可能会占用非核心资源。它通常还可以防止后续存储耗尽,这可能是一个瓶颈:如果存储缓冲区已满,则前端完全阻塞,并且新指令不再进入调度程序。

最后,像往常一样,一切都取决于周围代码的细节。如果重复运行该序列,并且foo() and bar()很短,与存储相关的未命中可能会主导运行时。毕竟,缓冲无法掩盖无限数量存储的成本。在某些时候,您将受到商店固有吞吐量的限制。

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

存储指令是否会在缓存未命中时阻塞后续指令? 的相关文章

随机推荐