当前位置: 首页 > 知识库问答 >
问题:

是移动拉克斯,0x12345678;jmp rax仍然杀死分支预测?

齐学文
2023-03-14

我很难找到上述两个案例的具体信息,尽管我想听听你的专家意见。

第一件事是:我知道间接jmp会损害分支预测,而且即使间接寻址的结果是恒定的,它仍然需要预测维护缓冲区和内容,所有这一切都与绝对jmp相比。

我的问题是,如果有人知道是否:

mov rax, 1234567812345678h;
jmp rax;

仍然被处理器的分支预测器认为是间接的,或者它在这种情况下做数学运算…我这样做是因为x64没有直接的“jmp绝对64”指令,只有间接的。:/(如何执行具有64位绝对地址的调用指令?建议这样做,如果你不能把跳转足够接近目标并使用jmp rel32。)

其次,从这个意义上说,jmp 0x1234和调用0x1234(在处理器优化(指令缓存,预取器及其提示,分支预测)方面)之间有什么真正的区别吗?(vc2012 “速度优化”产生调用,“min_size选择”产生jmp,“混合优化”产生x64的jmp,调用x86)

共有2个答案

林雅畅
2023-03-14

“我知道间接jmps会损害分支预测”

不。分支预测和间接跳跃预测是不同的。此外,间接跳跃用于基于表的开关语句和解释器中。这些是非常常见的用例,出现在基准测试中。因此,英特尔和其他公司花费了大量精力和大量晶体管来提高它们的性能。一篇论文(写在问题之后!)甚至说,从桑迪桥开始,在这种间接跳跃预测方面,你不应该相信民间传说。英特尔AMD有动力提高这种性能,他们做到了。

现在,如果您的jmp示例是冷代码,如果这是第一次执行它,则无法预测,而且Skylake间接跳转预测器将预测跳转后的下一条指令,并从那里进行推测。你可以用一个UD2,一个非法的指令来关闭这个推测。无论如何,第二次执行jmp时(如果它仍在BTB中),分支目标将是正确的。

至于你的第二个问题,缓存效果并不重要。我想较小的版本可以英勇地保存缓存行溢出,但仅此而已。硬件预取器用于数据,而不是指令。

孔欣荣
2023-03-14

英特尔的分支机构目标(和分支机构)预测是非常复杂的,也是一个秘密。不一定只有一种算法,也就是说,可以预期预测机制会随着CPU的不同而变化;这取决于英特尔想要解决给定处理器问题的晶体管数量。当然,除了英特尔,还有其他x86和x64处理器制造商。

历史分支目标预测机制 - 使用过去运行的相同指令来预测后续执行的目标 - 几乎肯定会预测此分支的正确目标,因为只有一个。因此,如果重新执行此代码序列(例如在循环中),并且它在指令缓存中保留一段时间,则可能会得到很好的处理。(但是,在某些处理器上,如果其他地方发生另一个分支导致哈希冲突,则分支目标预测机制可以通过与缓存行冲突类似的效果来中和。

一个更大的问题可能是,如果这种序列在新加载到高速缓存中的代码中大量出现,处理得如何,这涉及到处理器的非基于历史的目标预测能力。给定该代码序列,这种(非历史)分支目标预测可以容易地确定分支位置,尽管这完全取决于制造商是否认为它值得任何给定处理器的管芯上的不动产。做出这种决定的因素包括功耗、其他性能改进的折衷(即可能更好地使用相同的管芯面积)、以及这种和各种其他代码序列的预期频率。

 类似资料:
  • 问题内容: 我有一个运行bash脚本的詹金斯工作。 在bash脚本中,我有效地执行了两个操作,例如 但是如果手动中止了作业,则该作业仍然有效(如节点计算机上的a所示)。我无法使用陷印等等,因为如果jenkins发送信号(陷印不适用于),那将不起作用。 如果可以将此作业配置为简单地杀死它产生的 所有 进程,那将是理想的,我该怎么做? 问题答案: 实际上,默认情况下,Jenkins具有一个名为 Pro

  • 下面是我的Spock单元测试: 下面是mock: 当我运行此命令时,我得到: 它在第18行引用的空对象要么是,要么是它的映射。为什么啊?

  • 如果语句更多地依赖于分支预测,而v表查找更多地依赖分支目标预测,那么

  • 分支目标预测(BTP)与分支预测(BP)不同。我知道BTP会找到分支将跳转到的位置,而BP只是决定可能采取哪个分支。 BTP依赖BP吗,如果BTP不使用BP来预测哪个分支被采用,它怎么可能知道分支的目标呢? 我不明白为什么会有这么大的差异?一旦分支被预测为被占用,找到目标并不像读取指令中的地址一样简单吗?

  • 我的线程基本上是一些动作的循环。 我在循环中设置了一些检查,基本上检查布尔值是否仍然为真。布尔值在启动服务时设置为true,在停止服务时设置为false。更具体地说,我在我的服务类的ondestory()方法中将布尔值设置为false。 示例: 问题在于,当系统停止服务时,不会调用方法。那么,当服务不再运行时,如何正确地停止线程?