CPU 中的危险检测

CPU 中的危险检测

我有一个关于处理器的问题使用流水线

处理器采用指令流水线技术工作没有危险检测?

答案1

流水线处理器可以通过从不发生危险(可能在编译器调度的帮助下)或通过处理软件中的危险违规检测来避免所有硬件进行危险检测。

对于简单的标量流水线,结构风险相对容易避免,只需确保各阶段之间不共享硬件即可。这意味着单周期指令或完全流水线执行。

MIPS R2000 没有任何结构性风险,除了可能出现的乘法和除法(因为人们希望在开始另一次乘法或除法之前读取结果,因此尚不清楚是否可以将这些操作的流水线化视为硬件可以检测到的结构性风险)。如果将转发路径的选择视为不检测寄存器文件中结果延迟可用性的数据风险,则 MIPS R2000 仅具有与内存访问、乘法和除法相关的数据风险检测。对于 R2000,需要软件将 nop 放置在加载延迟槽中,但硬件确实可以检测并处理缓存未命中数据风险。

如果乘法的实现延迟为两个周期,那么要求编译器插入一个 nop(当从 HI 或 LO 的移动会立即跟在乘法或除法指令之后时,或者,如果这些指令使用通用寄存器作为目标,则当该 GPR 用作源时)来管理此数据风险可能是合理的。对于微控制器,没有缓存是可能的。这将只留下内存映射 I/O 作为数据风险的来源。微控制器中的一些片上外设可能能够支持非常短的固定延迟,可以通过延迟槽来处理(并且延迟槽的数量可能与实际内存访问不同如果编译器/程序员可以区分这两种情况)。

(检测缓存未命中的数据危险是相当自然的,因为处理器无论如何都必须检测缓存未命中。处理危险更加复杂。

处理器还可以将所有操作的延迟视为两个周期(如 R2000 中的缓存命中加载)。然后,编译器将负责将指令(可能是 nops)插入指令的延迟槽中。如果处理器是真正的桶式处理器,像桶上的木棍一样循环线程,那么可以为占用与“桶木棍”一样多的周期的操作提供单周期表观延迟;非活动线程有效地将 nops 插入延迟槽中。

使用简单流水线时,编译器可能会出现一些结构性风险,并避免这些风险。例如,处理器可能有两个寄存器组,每个寄存器组只有一个读取端口;编译器必须完全避免两个源指令的寄存器组冲突,可能的做法是插入寄存器复制指令,使两个寄存器组中的值都可用。

类似地,软件可以处理数据危险,其中最坏情况的延迟太大,无法简单地通过轮询就绪状态的自旋循环使用延迟槽。(就绪状态可能由硬件提供,或通过结果值检测如果为了保证结果不会具有特定值,可以预先将不可能的结果值插入长延迟操作目标寄存器。让硬件提供就绪状态,但不具备使用这种状态来检测危险的能力,这似乎很愚蠢,但这是可能的。)

粗粒度多线程是处理较长延迟的另一种方法。当最坏情况的延迟无法隐藏时,软件可以告诉处理器切换线程。如果软件保证此类较长延迟操作的重复率足够低,则两个线程可以隐藏可能引发数据危险的延迟。(如果硬件在解码此类操作时切换线程,即使软件也必须保证足够低的重复率,我也会将其视为危险检测。)

相关内容