0

让我们假设我有两个指针指向未缓存的不相关地址,因此它们在被取消引用时都必须从主内存一路来。

int load_and_add(int *pA, int *pB)
{
    int a = *pA;   // will most likely miss in cache
    int b = *pB;   // will most likely miss in cache 

    // ...  some code that does not use a or b

    int c = a + b;
    return c;
}

如果乱序执行允许在c计算 的值之前执行代码,那么在现代英特尔处理器上如何获取值ab继续进行?

潜在的流水线内存访问是否完全序列化,或者 CPU 的内存控制器是否执行了某种获取重叠?

换句话说,如果我们假设访问主存需要 300 个周期。获取ab花费 600 个周期,或者乱序执行是否会导致一些可能的重叠并且可能花费更少的周期?

4

1 回答 1

3

现代 CPU 具有多个负载缓冲区,因此可以同时处理多个负载。内存子系统是大量流水线的,它的许多部分提供了比延迟更好的吞吐量。(例如,通过预取,Haswell 可以维持(从主存储器)每 1 个时钟的 8B 负载。但是如果提前不知道地址,则延迟是数百个周期)。

所以是的,Haswell 核心可以跟踪多达 72 个等待来自缓存/内存的数据的未完成负载微指令。(这是每个内核的。共享的 L3 缓存还需要一些缓冲区来处理整个系统对 DRAM 和内存映射 IO 的加载/存储。)

Haswell 的 ReOrder Buffer 大小为 192 uopscode that does not use a or b ,因此可以发出和执行多达 190 uops 的工作,而a和的负载b是尚未退役的最旧指令。为了支持精确的异常,指令/微指令已停用。 ROB 大小基本上是无序窗口的限制,用于隐藏缓存未命中等慢速操作的延迟

标签 wiki 上的其他链接,了解 CPU 的工作原理。Agner Fog 的微架构指南非常适合拥有 CPU 管道的心智模型,让您大致了解代码将如何执行。

来自大卫坎特的 Haswell 文章英特尔 Haswell,来自 David Kanter 的文章

于 2016-05-02T19:46:54.363 回答