4

我无法找到上述两个案例的特定信息,尽管听取了您的专家意见。

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

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

mov rax, 1234567812345678h;
jmp rax;

处理器的分支预测器仍然认为是间接的,或者在这种情况下它是否进行数学运算。我这样做是因为 x64 没有直接的“jmp absolute 64”指令,只有间接的。:/ ( How to execute a call instruction with a 64-bit absolute address?建议这个,如果你不能把跳转足够靠近目标并使用jmp rel32。)


其次,在这个程度上,jmp 0x1234 和 call 0x1234 之间是否有任何真正的区别(在处理器优化方面(指令缓存、预取器及其提示、分支预测))?(vc2012“速度优化”产生调用,“min_size opt”产生jmp,“混合优化”产生x64的jmp,x86的调用)

4

2 回答 2

2

英特尔的分支目标(和分支)预测既非常复杂,又是一个保密的商业机密。不一定只有一种算法,也就是说,您可以预期预测机制会因 CPU 而异;这取决于英特尔希望针对给定处理器解决问题的晶体管数量。当然,除了英特尔,还有其他 x86 和 x64 处理器制造商。

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

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

于 2012-12-31T18:30:08.637 回答
1

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

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

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

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

于 2021-01-14T20:32:32.273 回答