我来写一点儿吧。

1.jmp和call,ret都是分支预测涵盖的范围。处理器内部有BTB+多级预测器,一般情况下可以很好地对付jmp和call指令,现在的综合分支预测成功率都在90%以上,不用程序员去考虑这么底层的东西,这是我们做CPU微结构的人才要考虑的。相互信任是很重要的,我们很相信上层的程序员写出的代码质量,也请程序员们相信我们做的微结构能够解决这些问题。话说学术界的人好像都觉得分支预测已经做到头了,最近我也没有看到啥有影响力的分支预测paper出来。

Bonus ——

2. 关于jmp的预测。有的指令集里面,jmp是表示无条件跳转,这种用BTB就能搞定,另一种是带条件测试的jmp,这就比较麻烦些,分支预测的原理主要是保存过去的分支历史记录,捕捉住某种模式,然后预测未来。如果每次条件测试的结果都没什么规律可循,那么再强的预测器也得抓瞎。所幸现在大部分jmp都是有明显规律可循的,可以比较好地预测,对于那些不好预测的,可以由编译器自动地,或者由程序员手工地,转化成谓词指令。我倒是见到有些追求极致性能的程序员,会把关键函数中的一些难于预测的小分支,用内联汇编的方式,手工转成谓词指令。

3.关于call/ret的预测。函数调用的call/ret有一个叫做return stack predictor的东西在负责,这个东西不是完美无缺的,也会出错。举个例子,call和ret指令本来是配对存储在return stack里面的(有的架构里面可能没有ret,暂且不考虑这种情况),但是分支预测的时候,比如在一条错误的执行路径上遇到了call/ret,就会错误地push/pop不正确的地址,导致配对失准,需要repair stack。一段精心设计的代码可以把CPU的prefetcher,branch predictor,return stack,Instruction Cache全部搞得一塌糊涂,这些属于比较极端的情况,一般情况下不用程序员考虑这么深。

4. 指令延迟槽这种很早就不够用了,分支太多,延迟槽填不过来。

— 完 —

本文作者:破布

【知乎日报】
你都看到这啦,快来点我嘛 Σ(▼□▼メ)

此问题还有 3 个回答,查看全部。
延伸阅读:
为什么CPU流水线设计的级越长,完成一条指令的速度就越快?
指令集流水线(pipeline)这一性能指标是在 CPU 内部定义的吗?是不是做为 CPU 的一个参数,还是以其他方式规定的?

分享到