与 x86 相关:为什么要为其他逻辑处理器导致的 Memory Order Violation 刷新管道?. 可观察到的结果将遵守 x86 排序规则,但在微架构上是的,它可以提前加载。(当然这是来自缓存;硬件预取是不同的)。
如果地址还没有准备好进行一次加载,OoO exec CPU 确实会重新排序加载执行。或者,如果它在缓存中丢失,则以后的加载可以在数据到达之前运行。但是在 x86 上,要保持正确性。强内存模型(程序顺序 + 带有存储转发的存储缓冲区),核心根据 ISA 的纸上内存模型保证检查最终结果是否合法。(即之前加载的缓存行仍然有效,因此仍然包含我们现在允许加载的数据)。如果没有,请取消依赖于这种可能不安全的推测的飞行指令并回滚到已知的安全状态。
因此,现代 x86 获得了轻松加载排序的性能(大部分时间),同时仍然保持每个加载实际上都是获取加载的内存模型规则。但是,如果你做了一些管道不喜欢的事情,例如虚假共享(这已经够糟糕的了),就会以管道核武器为代价。
其他具有强内存模型 (Sparc TSO) 的 CPU 可能不会这么激进。弱内存模型允许稍后的加载提前完成。
当然这是从缓存中读取的;仅在高速缓存未命中时,内存控制器才会看到需求加载请求。但是硬件预取器可以从 CPU 异步访问内存;这就是他们在 CPU 运行加载它的指令之前将数据放入缓存的方式,理想情况下完全避免缓存未命中。
是的,内存子系统是流水线的,就像 Skylake 中每个核心有 12 到 16 个未完成的请求一样。(L1<->L2 的 12 个 LFB,以及 L2 中的 IIRC 16 个超级队列条目。)