我观察到大多数不错的编译器可以在不同程度上预先计算指针间接 - 可能会删除大多数分支指令 - 但我感兴趣的是间接成本是否大于分支的成本指向生成的代码。
我希望如果指针引用的数据在运行时不在缓存中,可能会发生缓存刷新,但我没有任何数据可以支持。
是否有人对此事有确凿的数据(或合理的意见)?
编辑:有几张海报指出,分支成本没有“一般情况”:芯片之间的差异很大。
如果您碰巧知道一个值得注意的案例,其中分支会比缓存间接更便宜(有或没有分支预测),请提及它。
答案 0 :(得分:4)
这在很大程度上取决于具体情况。
1缓存中的数据(L1,L2,L3)的频率是多少,以及从RAM一直提取的频率是多少?
从RAM获取大约需要10-40ns。当然,这将填充整个缓存行,而不是那么多,所以如果你再使用接下来的几个字节,它肯定不会“伤害那么糟糕”。
2它是什么处理器?
较旧的英特尔奔腾4以其漫长的流水线阶段而闻名,并且需要25-30个时钟周期(2GHz时约15ns)从错误预测的分支“恢复”。
3条件如何“可预测”?
分支预测确实对现代处理器有所帮助,它们也可以很好地处理“不可预测”的分支,但它确实有点伤害。
4缓存如何“忙”和“脏”?
如果你必须丢弃一些脏数据来填充缓存行,那么在“获取数据”时间内还需要15-50ns。
间接本身将是一个快速指令,但当然,如果下一条指令立即使用数据,您可能无法立即执行该指令 - 即使数据在L1缓存中。
在美好的一天(很好地预测,目标在缓存中,风向正确方向等),另一方面,分支需要3-7个周期。
最后,当然,编译器USUALLY非常清楚最有效的方法......;)
总之,很难肯定地说,在你的情况下告诉什么更好的唯一方法是对替代解决方案进行基准测试。我会认为间接内存访问比跳转更快,但是没有看到你的源编译的代码,很难说。
答案 1 :(得分:3)
这真的取决于你的平台。没有看目标CPU的内部,没有一个正确的答案。我的建议是在测试应用程序中测量它,看看是否有明显的差异。
我的直觉就是在现代CPU上,通过函数指针和条件分支进行分支都依赖于分支预测器的准确性,所以如果预测器具有类似的预测器,我期望这两种技术具有相似的性能工作负载。 (即如果它总是以相同的方式结束分支,期望它快速;如果很难预测,那么它会受到伤害。)但唯一可以确定的方法是在目标平台上进行真正的测试。 / p>
答案 2 :(得分:2)
这取决于处理器与处理器之间的关系,但是根据您正在使用的数据集,由错误预测的分支(或某些情况下排序错误的指令)导致的管道刷新可能比简单的更具破坏性缓存未命中。
例如,在PowerPC的情况下,未采用(但预计采用)的分支花费大约22个周期(重新填充流水线所花费的时间),而L1缓存未命中可能花费600个左右的存储周期。但是,如果您要访问连续数据,最好不要分支并让处理器以3个周期(预计将采用和分支)的成本缓存错过您的数据对于您正在处理的每组数据。
这一切归结为:自己测试一下。对于所有问题,答案是不确定。
答案 3 :(得分:0)
由于处理器必须预测条件答案以便计划哪个指令有更多机会被执行,我会说指令的实际成本并不重要。
条件指令效率很低,因为它们会使流程不可预测。