x86-64管道是否像JMP RAX那样间接跳转?

cra*_*dr4 2 assembly pipeline x86-64 intel nasm

在x86-64中,如果使用以下汇编代码:

MOV RAX, (memory address)
JMP RAX
Run Code Online (Sandbox Code Playgroud)

管道在执行分支之前是否停止(等待MOV完成RAX),还是像条件分支一样刷新管道?

Bre*_*dan 5

对于大多数现代80x86 CPU; 有静态预测(没有用于做出更好预测的历史记录)和动态预测(其中有可以使用的先前执行的历史记录).

对于静态预测,CPU预测执行将在紧随其后的指令处继续执行JMP RAX.我不完全确定哪些CPU使用动态预测JMP RAX(而不仅仅是Jc分支); 但对于那些做它的人来说,它会覆盖静态预测.

一旦CPU具有预测的目标地址,它就会推测性地执行,直到它发现它是否正确/错误.如果它预测得对,它会保留它所做的所有工作,并且JMP RAX几乎没有成本.

如果CPU预测错误,那么这与任何其他分支错误预测没有区别(丢弃所有推测性执行的工作并返回到正确RIP处获取/解码).

请注意,如果您JMP RAX的指令不可预测,或者它之后的指令不太可能成为跳转的目标; 英特尔建议在跳转之后PAUSEUD2之后立即进行,以防止不必要的推测性执行.在这种情况下,CPU将停止(在找到正确的跳转目标之前不做任何事情).

另请注意,您希望移动它MOV RAX, ..以便尽快执行,以便尽快知道跳转的目标,以便最大限度地减少停滞或推测性地执行错误操作所花费的时间.

  • @PeterCordes:在大多数版本的英特尔优化指南中,它都会说(从2012年4月版本的"E.1规则13"中几乎逐字逐句):"当存在间接分支时,尝试将最可能的目标放在间接分支紧跟在间接分支之后.或者,如果间接分支是常见但无法预测,则使用UD2指令跟随间接分支,这将停止处理器沿着直通路径解码".当然,整个指南中提供了更多细节(我精简到符合评论框字符限制) (3认同)