已退役(Retired) vs. 已执行(Executed)指令
现代处理器通常执行的指令数量比程序流程所需的要多。这是因为一些指令是以推测性的方式执行的,如[@sec:SpeculativeExec]中所讨论的。对于大多数指令,CPU在结果可用时提交,所有先前的指令都已退役(retired)。但对于以推测性方式执行的指令,CPU会保留它们的结果,而不立即提交它们的结果。当推测结果被证明是正确时,CPU会解除此类指令的阻塞并正常进行。但当推测结果被证明是错误时,CPU会丢弃推测指令所做的所有更改,并不会退役它们。因此,CPU处理的指令可以被执行但不一定被退役。考虑到这一点,我们通常可以预期执行的指令数量高于已退役的指令数量。
但有一个例外。某些指令被识别为惯用语,并且在没有实际执行的情况下被解析。其中一些示例是NOP、移动消除和清零,如[@sec:uarchBE]中所讨论的。这些指令不需要执行单元,但仍然被退役。因此,从理论上讲,可能存在已退役指令数量高于已执行指令数量的情况。
大多数现代处理器都有一个性能监视计数器(PMC),用于收集已退役指令的数量。虽然没有性能事件来收集已执行的指令,但有一种方法可以收集已执行和已退役的微操作,我们很快将会看到。可以通过运行以下命令轻松获取已退役指令的数量,使用Linux perf
:
$ perf stat -e instructions ./a.exe
2173414 instructions # 0.80 insn per cycle
# 或者简单地执行:
$ perf stat ./a.exe