即使 RS 未完全充满,RESOURCE_STALLS.RS 事件是否也可能发生?

Had*_*ais 5 performance x86 intel cpu-architecture intel-pmu

RESOURCE_STALLS.RSIntel Broadwell 硬件性能事件的描述如下:

此事件对由于保留站 (RS) 中缺少合格条目而导致的停顿周期进行计数。这可能是由于 RS 溢出,或由于 RS 阵列写入端口分配方案导致的 RS 解除分配(每个 RS 条目有两个写入端口而不是四个。因此,无法使用空条目,尽管 RS 并未真正满) . 这计算管道后端阻止来自前端的 uop 传递的周期。

这基本上说有两种情况会发生 RS 停顿事件:

  • 当RS 的所有符合条件的条目都被占用并且分配器没有停止时。
  • 当因为只有两个写端口而发生“RS 解除分配”时,并且分配器没有停止。

在第一种情况下,“合格”是什么意思?这是否意味着并非所有条目都可以被各种 uop 占用?因为我的理解是,在现代微体系结构中,任何条目都可以被任何类型的 uop 使用。还有什么是 RS 阵列写入端口分配方案,即使并非所有条目都被占用,它如何导致 RS 停顿?这是否意味着 Haswell 中有四个写端口,而现在 Broadwell 中只有两个?即使手册没有明确说明,这两种情况是否适用于 Skylake 或 Haswell?

Had*_*ais 4

我编写了一个程序,可用于探索英特尔处理器中 RS 的未记录限制,希望我最终能够回答这个问题。基本思想是在循环中分配和执行特定的微指令序列之前确保 RS 完全为空。可RESOURCE_STALLS.RS用于确定该序列是否达到 RS 本身的限制。例如,如果RESOURCE_STALLS.RS每次迭代为 1,则分配器必须停止一个周期才能为序列中的所有微指令分配 RS 条目。如果RESOURCE_STALLS.RS每次迭代远小于 1,那么它基本上不必停止,所以我们知道我们没有遇到任何 RS 限制。

我已经尝试过一系列相关ADD指令、一系列相关 BSWAP 指令、一系列到同一位置的相关加载指令、一系列向后或向前无条件跳转指令以及一系列到同一位置的存储指令。下面两张图显示了add不同目标 RS 占用率(微指令序列同时需要和占用的 RS 条目的最大数量)的指令序列的结果。每次迭代都会显示所有值。

下图显示,RESOURCE_STALLS.RS当 RS 占用率为 50 时,每次迭代至少(或接近)每次迭代 1 个周期。虽然不明显可见,但当RESOURCE_STALLS.RSRS 占用率超过 43 时,它会变得大于零,但仅当 RS 占用率超过 1 时占用超过 49。换句话说,我最多只能同时使用 60 个 RS 条目中的 49 个(在 Haswell 中),而不会出现 RS 停顿。此后,序列中每增加一个 uop,平均增加 1,这与分配器的突发行为以及每个uop 可以在每个周期完成的RESOURCE_STALLS.RS事实一致(每个 uop 仅占用一个 RS 条目 1 个周期)。每增加一个 uop,平均增加 2.3。每个额外的微指令都大于 1,因为由于与微指令无关的原因,ROB 上还存在额外的停顿,但这些都可以,因为它们不会影响。ADDcyclesaddRESOURCE_STALLS.RS

在此输入图像描述

cycles下图显示了每次迭代中的变化RESOURCE_STALLS.RS。它说明了执行时间和 RS 停顿之间的强相关性。

在此输入图像描述

当目标 RS 占用率在 44-49 之间时,RESOURCE_STALLS.RS非常小,但仍然不是真正的零。我还注意到,不同微指令呈现给分配器的确切顺序会稍微影响可以达到的 RS 占用率。我认为这是Intel手册中提到的RS阵列写端口分配方案的效果。

那么其他 11 个 RS 条目(Haswell 的 RS 应该有 60 个条目)怎么样了?演出RESOURCE_STALLS.ANY事件是回答问题的关键。我已经更新了用于执行这些实验的代码,以测试不同类型的负载:

  • 可以使用推测地址分派负载以实现 4 个周期的 L1D 命中延迟。此案简称loadspec
  • 无法使用推测地址分派的负载。它们在 Haswell 上的 L1D 命中延迟为 5 个周期。此案简称loadnonspec
  • 可以使用推测但不正确的地址分派负载。它们在 Haswell 上的 L1D 命中延迟为 9 个周期。此案简称loadspecreplay

我按照说明遵循相同的方法ADD,但这次我们需要观察RESOURCE_STALLS.ANYRESOURCE_STALLS.RS实际上不会捕获由于负载而导致的 RS 停顿)。cycles下图显示了每次迭代中的变化RESOURCE_STALLS.ANY。第一个尖峰表示目标 RS 占用率已超过该类型 uop 的可用 RS 条目。我们可以清楚地看到,对于这种loadspec情况,正好有 11 个用于加载微指令的 RS 条目!当目标 RS 占用率超过 11 时,RS 条目平均需要 3.75 个周期才能空闲到下一个加载 uop。这意味着微指令在完成时从 RS 中释放,而不是在它们被调度时。这也解释了 uop 重放的工作原理。的峰值loadspecreplay出现在 RS 占用 6 时。峰值loadnonspec出现在 RS 占用 9 时。正如您稍后将看到的,这 11 个条目并非专用于负载。负载使用的 11 个条目中的一些可能位于微指令使用的 49 个条目中ADD

在此输入图像描述

我还为存储开发了两个测试用例:一个达到存储缓冲区的限制,另一个达到 RS 的限制。上图显示了前一种情况。请注意,存储需要 RS 中的两个条目,因此目标 RS 占用率为奇数的情况与之前的偶数 RS 占用率相同(变化为零)。该图显示 RS 中最多可以同时有 44/2 = 22 个存储。(我用来制作商店图的代码有一个bug,会导致实现的RS占用率比实际的要大。修复后,结果显示RS中最多可​​以同时有20个商店。)存储地址或存储数据微指令占用的条目可以在一个周期内释放。Intel 表示 Haswell 的存储缓冲区有 42 个条目,但我无法同时使用所有这些条目。我可能需要设计一个不同的实验来实现这一目标。

跳跃序列没有导致任何停顿。我认为这可以解释如下:跳转微指令释放它在一个周期内占用的RS条目,并且分配器在分配跳转微指令时不会以突发方式运行。也就是说,每个周期一个 RS 条目变得空闲,并且分配器将仅分配一个跳转 uop 而不会停止。因此,无论有多少个跳跃微指令,我们最终都不会停止。这与添加微指令相反,其中突发分配器行为使其停止,直到所需数量的 RS 条目变为空闲(4 个条目),即使添加微指令的延迟也是一个周期。尽快分配跳跃是有意义的,以便尽早检测到任何错误预测。因此,如果分配器看到跳转并且 RS 中有足够的空间供其使用,但其 4 uop 组中没有后续的 uop,那么它仍然会分配它。否则,它可能必须等待潜在的许多周期,这可能会显着延迟错误预测的检测。这可能会非常昂贵

是否有一条指令的uop可以同时占用RS的所有60个条目?是的,一个例子是BSWAP。它的两个 uops 需要两个 RS 条目,我可以清楚地看到RESOURCE_STALLS.RS,它的 uops 可以同时使用 RS 的所有 60 个条目(假设我的计算关于 RS 占用率如何使用该指令增长是正确的)。这证明RS中确实有60个条目。但我们对它们的使用方式仍然知之甚少。

  • [这张幻灯片](https://images.anandtech.com/doci/13699/Ronak20.jpg) 可能相关。“Skylake 提醒”幻灯片暗示有_两个_独立的 RS:一个用于所有 ALU 端口,一个用于加载/存储端口(并且在 ICL 中增加到 4 个:一个用于存储数据,每个用于存储数据)加载/存储 AGU)。这意味着加载和存储 RS 条目可能来自单独的池?我认为你在测试中确实发现了他们之间的一些竞争...... (2认同)