在以下伪代码中:
if (rdtscp supported by hardware) {
Invoke "rdtscp" instruction
} else {
Invoke "rdtsc" instruction
}
假设 CPU 不支持该rdtscp
指令,所以我们回退到 else 语句。
如果 CPU 错误预测了分支,指令流水线是否有可能尝试执行rdtscp
并抛出Illgal Instruction
错误?
在以下伪代码中:
if (rdtscp supported by hardware) {
Invoke "rdtscp" instruction
} else {
Invoke "rdtsc" instruction
}
假设 CPU 不支持该rdtscp
指令,所以我们回退到 else 语句。
如果 CPU 错误预测了分支,指令流水线是否有可能尝试执行rdtscp
并抛出Illgal Instruction
错误?
在英特尔处理器手册第 3A 卷第 6.15 章中明确记录了#UD 陷阱(无效的操作码执行):
在实现乱序执行微架构的 Intel 64 和 IA-32 处理器中,直到尝试退出执行无效指令的结果时才会生成此异常;也就是说,解码和推测性地尝试执行无效的操作码不会生成此异常。同样,在 Pentium 处理器和更早的 IA-32 处理器中,不会由于预取和初步解码无效指令而生成此异常。
指令陷阱,例如“非法指令”陷阱,在指令执行时生效,而不是之前。程序通常取决于程序在陷阱被抛出的那一刻处于什么状态,因此提前执行它们将是架构中的一个严重错误。
编辑:好的,好的。来自英特尔软件开发人员手册,第 3A 卷:
P6 系列处理器推测执行指令的能力不会影响处理器对中断的处理。中断发生在指令执行的退出阶段的指令边界处;所以它们总是被按“顺序”指令流处理。
这取决于您如何定义“原因”。它可以产生一些可观察的效果吗?是的。
正如 Hans 和 Sneftel 所指出的 - 异常、中断、陷阱等都在退休时发生,错误路径代码永远无法到达。因此,错误预测的分支不会导致错误路径指令的提交/退出,包括它们可能尝试执行的任何非法操作码。
但是,错误预测的代码路径可能会以更微妙的方式影响微架构状态,您可能已经执行和缓存了加载、完成了页面遍历以及各种其他微架构事件 - 简而言之,您的 CPU 所做的所有艰苦工作而你不小心去错误地预测了一些分支(这在 OOO CPU 中相当多)。我非常怀疑那里的任何 CPU 都会将所有这些东西从你的缓存/TLB 中捞出来,所以要考虑到这些东西以后会影响你的程序的性能(无论好坏),只是不在其功能行为上。
如果您从事优化性能的业务(并且可能太复杂而无法使用),这可能不值得,但如果您从事保护代码的业务,则可能需要考虑 - 有些黑客可能有办法从缓存中嗅探此类数据。