存储单元也是英特尔处理器上的加载单元吗?

Is Store Unit Also a Load Unit on an Intel processor?

大多数英特尔处理器有 2 个加载单元和 1 个存储单元。 存储单元也是负载单元吗? 修改 现有内存数据(如inc [memory])的指令/微操作是否仅使用 1 个存储单元,其余 2 个加载单元可用于其他 micro-ops/instructions在相同的周期内执行,或者像 inc 这样的指令需要 1 个加载单元(加载现有值)加上 1 个存储单元(存储新值)所以我们只剩下一个可用的加载单元?因此,为了保持 2 个负载单元可用,我们可以 存储指令,如 movpush 等?

内存读取-修改-写入指令在 Intel P6 系列或 Sandybridge 系列上至少有 4 个未融合域微指令。 (如果它需要超过 1 个 ALU uop,它可能会更多)

不要求它们中的任何一个在同一个周期中执行,你的问题的措辞似乎是假设的。允许乱序执行在加载使用延迟期间做其他工作是将 x86 指令解码为内部 RISC 类 uops 的主要好处之一。

您可以在 Agner Fog's instruction tables 中查看更多详细信息。查阅他的微体系结构 pdf 以了解有关其含义的更多信息。对于我在此答案中未解释的任何内容,您可以在其中找到详细信息。

对于 Intel Haswell 上的 inc dword [rdi],这些是 uops(以及它们可以 运行 的端口):

  • 加载dword [rdi](p2/p3),取决于rdi
  • ALU inc (p0/p1/p5/p6),取决于加载的数据
  • store-address [rdi] (p2/p3/p7),取决于rdi(我认为不是加载的数据)
  • store-data (p4) 将 ALU 结果复制到存储缓冲区,我认为这取决于 ALU 和存储地址 uops。

请注意,只有简单的寻址模式([reg][reg + constant])可以使用端口 7 上的 AGU,但它们仍然可以发送到 p2 或 p3 并窃取负载吞吐量。其他存储寻址方式只能使用p2/3。 load uops到p2或p3,用AGU也用执行单元的load-data部分。

这种不完美的调度可以而且确实会影响持续的 L1D 带宽:Intel 的优化手册建议尽管 Skylake-S 中的 peak L1D 带宽在单个周期内读取 64B 和写入 32B,持续 带宽最多为每个周期约 81B。 (Table 2-4. Cache Parameters of the Skylake Microarchitecture on page 36)

inc [mem] 肯定要 运行 加载 uop。有关读取-修改-写入操作如何工作的更多详细信息,请参阅 (with/without lock 前缀)。 CPU 不能只向 DRAM 或缓存​​发送 "increment" 命令并让操作发生 "in memory".


计算 uops 与端口对于循环或长代码序列中的吞吐量更有意义。您无法知道哪些 uops 将在彼此相同的周期内执行,除非它们都在等待相同的输入准备就绪。然后,您可以预测,如果没有足够的执行端口让 uops 并行执行 运行,那么最旧的 uop 将首先执行(这称为资源冲突)。因此,最好先将指令放在关键路径上,以减少资源冲突造成的延迟。

特定端口上的执行端口瓶颈只是三种常见的 uop 吞吐量之一。另外两个是:

  • 限制可用的延迟/依赖链ILP
  • 每个时钟 4 个融合域 uops 的前端限制,而不是任何特定端口上的非融合域压力。 (或者在 Ryzen 上为 5,在 运行ning 多 uop 指令时为 6)。

因此,除了缓存未命中和分支预测错误之外,指令序列对周围独立工作的影响可以粗略地通过其延迟、融合域微指令计数和每个端口的微指令来表征。


为了节省前端解码和发布带宽,其中一些微指令可以微融合在一起。 (或者 AMD CPUs 从来没有把它们分开,直到它们到达执行单元)。有关微聚变的更多信息,另请参阅 Micro fusion and addressing modes。 (我对该答案有一个未完成的更新,它添加了微融合的独立描述以将所有内容放在一个地方,因为 Agner Fog 的指南省略了未层压并且英特尔的优化手册没有提到 HSW,后来也没有提到在 SnB 这样做的情况下总是不层压。)

inc dword [rsi] 只能在 Sandybridge-family 上将存储地址 + 存储数据微指令融合在一起,因此它解码为 3 微指令。

add dword [rsi], 1 可以将负载与 ALU add 微指令融合,因此从 IDQ 读取并添加到 ROB 的问题阶段只有 2 个融合域微指令。它仍然扩展到 4 个未融合的域 uops 以分配给端口并添加到调度程序(又名保留站)。 (是的,在 Intel CPUs 中 uops 被分配给端口)。

请注意 add 设置的标志与 inc 不同,因此它们无法解码为完全相同类型的内部 uop。据推测,英特尔认为让 add uops 熔断负载是值得的,因为像 add eax, [rsi] 这样的指令很常见。但是 inc + 负载融合只能作为 inc [mem].

的一部分发生