分支预测会破坏我的程序吗?

Ale*_*x C 14 x86 assembly computer-architecture branch-prediction

本书的第3章称为计算机系统架构:程序员的观点,它表示一个类似的实现

testl %eax, %eax
cmovne (%eax), %edx
Run Code Online (Sandbox Code Playgroud)

是无效的,因为如果预测失败,那么我们将有NULL解除引用.还声明我们应该使用分支代码.

不过,不使用条件跳转会导致相同的结果吗?例如:

.L1:
jmp *%eax

testl %eax, %eax
jne .L1
Run Code Online (Sandbox Code Playgroud)

是否有可能欺骗gcc为x86-32输出类似的内容?假设我有一个指向函数的指针数组,其中一些是有效的,有些则不是,我称每个函数都不是NULL.

Gen*_*ene 5

不可以.jmp如果它是由于测试和跳转而证明无效的推测性执行的一部分,则您不应该检测到指令的无序操作数获取.

如果内存访问操作数会导致错误,即使不满足条件,也会精确记录cmove__指令以导致错误.换句话说,这不是推测性执行.它是指令语义的一部分.这是移动到desination这是有条件的,不是取.

jmp指令没有记录在案.

我没有明白你的示例代码,因为内存操作没有条件*%eax.如果%eax包含零,则无条件执行中的提取肯定jmp *%eax会导致错误.这是正确的行为.如果你测试%eax并跳转坏参考.

testl %eax, %eax
je .L1
jmp *%eax
.L1:
Run Code Online (Sandbox Code Playgroud)

不会有问题.*%eax除非推测证明是有效的,即推测执行不会导致错误,即真正的控制路径.这类似于坏操作码的行为,除以零等:正常的程序语义不受推测执行的影响.

凡乱序读取并存储真正做到使各种有趣的问题是在多处理. 本文以及前一个问题的第一部分是对该主题的深入讨论.