CPU中哪个执行单元执行预取指令?

问题描述 投票:0回答:1

根据Intel手册,预取指令一般不会触发故障或异常,这与常规加载指令不同。

PREFETCH给硬件提供一个提示; 除了少数特殊情况外,它不会生成异常或故障(请参见第 9.3.3 节“预取和加载指令”)。然而,过度使用 PREFETCH 指令可能会浪费内存带宽,并因资源限制而导致性能损失。

考虑到CPU微架构中的不同端口用于处理不同类型的指令,(软件)预取和加载指令在μop调度和执行阶段也使用相同的端口吗?

硬件预取怎么样?

cpu cpu-architecture prefetch
1个回答
1
投票

硬件预取不使用执行单元;例如,一个单独的硬件可以生成额外的请求,将数据拉入 L2 或 L1d。不是通过将要执行的微指令送入指令流。类似于页面遍历器如何与加载执行单元并行地向 L1d 生成额外的加载请求。 (可能与它们竞争有限的缓存读取端口。端口如多端口 SRAM 中的端口,而不是执行端口/单元中的端口。)


软件预取在加载执行单元上运行。它需要地址生成,并且需要几乎完全像加载一样工作,即使对于 x86

prefetchw
或同等版本(写入意图,即使用 Read For 预取到 MESI Exclusive 状态)所有权。如果缓存中不存在,这仍然是一个负载。)

如果任何 ISA 的任何微架构对于软件预取和加载都有不同的执行单元,我会感到惊讶。 (除非 ISA 与 x86 和 AArch64 等主流 ISA 非常不同。)

不出现故障实际上非常容易:正常的需求负载只有在达到退休状态(变得非投机性)时才会出现故障。处理此问题的正常方法是,跟踪它的 ROB(重新排序缓冲区)条目被标记为如果退出则引发异常,作为加载执行单元的一部分,完成执行 uop 的工作并将 ROB 条目标记为完成(就绪)退休)。因此,每个 ROB 条目已经有一个故障或无位,或者可能有多个位来确定哪种故障。事实上,故障负载在退役之前不会做任何特别的事情,这是 Meltdown 的关键之一(连同转发到相关 uops 的实际数据,这些数据永远不会在架构上变得可见......除非通过计时侧通道。)参见 无序执行与推测执行,了解有关推测执行如何工作的更多详细信息。据我所知,所有乱序执行 CPU 都使用相同的策略,即在报废之前不对错误指令执行任何操作;是否容易受到 Meltdown 影响取决于依赖的 uops 是否在错误加载后执行,如果是,它们会看到什么数据。 (例如,始终为零就可以了。)

软件预取指令根本不会在 ROB 条目中设置退休故障位,无论页面遍历的地址或结果如何。(即使是非规范地址也不会在 x86-64 上出现故障) .) 它们只是提示,因此如果两个页面遍历单元都忙于 TLB 未命中预取,CPU 可能会选择不等待页面遍历。

相同的退休故障机制用于使所有指令的推测执行成为可能,包括像

div
这样可能因其他原因而发生故障的指令,以及正常的需求负载。 (较旧的 CPU 曾经以相同的方式处理分支,仅从退役时的错误预测中恢复,但分支很特殊,真实的程序确实在快速路径上有分支错误预测,因此额外的硬件(“分支顺序缓冲区”)可以实现“快速恢复”, 从首次检测到错误预测时开始。)

诀窍在于,每条指令在退出之前都被视为推测指令,无论最近是否执行过任何分支或可能出错的指令。可能出错或错误预测的指令在实际代码中太常见,无法针对任何其他情况进行优化。

唯一没有解决的问题是存储:错误推测的存储数据不得对其他核心可见。通常这意味着我们不能让它们直接写入 L1d 缓存。存储缓冲区是该问题的解决方案:推测执行的 CPU 分支是否可以包含访问 RAM 的操作码?


对于 x86,您可以检查 https://uops.info/ 并看到它们使用 Intel CPU 上的负载端口。 (例如 Skylake / Ice Lake 中的端口 2 或 3,或 Alder Lake 中的端口 2/3/A)。 uops.info 实际上没有 AMD 对于大多数非 SIMD 指令的执行端口详细信息,但那里也一样。

© www.soinside.com 2019 - 2024. All rights reserved.