2015-08-29 15 views
2

我想知道一个乱序超标量处理器(让我们假设一个Intel i7处理器)的每个周期的提取指令数量是否不变,或者它可能会根据缓存未命中率或分支未命中预测数量给定的代码/程序?如果无序超标量处理器的每个周期取指令的数量是恒定的?

如果不是恒定的,该如何解释它背后的原因?据我所知,在现代多核处理器中,解码器单元总是试图解决依赖关系,并尝试用独立指令填充管道气泡。因此,对于任何给定的工作负载,提取的指令数量不应总是相同(大约)?

+2

每个周期取指令*字节*的数量通常是恒定的,但是对于可变长度指令(或从取块中间离开或进入的分支),取指令的数量将趋于变化。使用Pentium Pro型约束解码器(其中只有第一条指令可以解码为多个μops),每个周期解码的指令数可以少于取块中的数(如果第二条指令将解码为多个μops,则它必须等待直到下一个周期)。 (稍后可以发布实际答案。) –

回答

5

在给定周期内获取的指令数取决于多个因素。对于Intel第四代Core处理器,当使用指令缓存而不是μop缓存时,每个周期都会获取一个对齐的16字节指令块。从这个块到最多六个指令可以被解析并放置在一个指令队列中(最多可以容纳来自线程的20条指令)。如果可以融合两条指令(也称为宏操作),则第一指令解码为不超过四个融合的微指令,并且其余三条指令解码为单一融合的微指令,则来自该队列的多达五条指令可以被解码。得到的μops存储在一个56个条目的μop解码队列中(也可用作循环缓冲区)。 (解码为四个以上μops的指令使用特殊的微码引擎。)

由于x86具有可变长度指令(长达15个字节),因此16字节块中的指令数量可能会有所不同。另外,对于采用分支,分支的目标可能不会与16字节块对齐,并且分支指令可能不会在块的最后一个字节上结束;这意味着具有未对齐的采纳分支目标的块的开始处的字节将被忽略,并且在采取的分支之后的块内的字节将被忽略。如果分支目标缓冲区和指令高速缓存具有两个周期延迟,则在采用的分支上,在该分支之后的周期中,分支指令开始被提取将不会有目标可用于获取以下指令)

如果存在指令高速缓存未命中,则不会从该线程获取指令,直到缺少高速缓存行变为可用。类似地,在从指令高速缓存进一步获取之前,必须服务TLB未命中。

μop缓存对每个周期读取的指令数量有不同的限制。每个周期可从μop缓存中读取四个μops。这可以对应于一条指令或(与宏操作融合)超过四条指令。由于μop缓存被虚拟寻址,因此TLB未命中不会延迟读取(尽管在μop缓存命中时TLB未命中不太可能)。

(四μops可以从μop解码队列移动到60-条目调度每个周期。)

随着分支误预测,由于管道被冲洗,没有一个分支之后取出的指令将有助于获取有效指令的次数。在检测到分支错误预测之前,指令将被提取(有些可能被执行),但它们不会影响提交的指令数量。

此外,指令的缓冲量有限。如果依赖于具有数据高速缓存未命中调度缓冲区的负载的μops可能会被填满,这会导致指令在μop解码队列中累积(因为该队列将不再被排空),然后紧接在获取之后的指令队列会很快因为它不能流入μop解码队列。

排序缓冲区(ROB)对离开μop解码队列的指令放置了另一个限制;当ROB满时,没有更多的指令可以移入调度缓冲区。如果最老的指令尚未完成,即使所有以下191条指令已完成并准备提交,也会发生这种情况。

即使没有数据高速缓存未命中,操作之间的依赖关系也会导致缓冲区填满,从而导致取指操作停止。你可能会猜到,拥有第二个线程可以通过减少分支预测的影响(实际上只有一半的指令从流水线刷新)并提供更多的指令级并行性(因为指令从独立的线程将是独立的),它允许操作执行并最终提交,排空各种缓冲区。由于存在指令的这种实质缓冲,并且大多数软件不能一致地充分利用执行宽度,所以获取尽可能多的指令的压力较小,因为每个循环可能执行的指令较少。高质量的分支预测也意味着更多的获取指令将被实际使用。 (在分支错误预测中,更广泛的获取会更快地填满调度缓冲区,从而增加了独立操作的可能性。由于多线程增加了可用的指令级并行度,这也为更广泛的获取提供了动机,但它也是降低了取消档位的频率和成本以抵消该激励)。

+0

非常感谢您的详细解释! – precision

1

为了说明这一点,我们看看this文档,其中显示了不同体系结构以“并行”方式执行某种类型指令的能力。正如您所理解的,将一种延迟类型的指令与其他指令组合起来可以使CPU以不同方式适应混音。因为它们可能依赖于相同的寄存器,缓存未命中,分支预测失误(或其他不太明显的因素),交互变得更加复杂。

+0

谢谢!这是一个很棒的文件。 – precision