6

指针间接(获取值)是否比条件更昂贵?

我观察到大多数体面的编译器可以在不同程度上预先计算指针间接 - 可能会删除大多数分支指令 - 但我感兴趣的是间接成本是否大于分支点的成本生成的代码。

我希望如果指针引用的数据在运行时不在缓存中,则可能会发生缓存刷新,但我没有任何数据来支持它。

有人对此事有可靠的数据(或合理的意见)吗?


编辑:几位张贴者指出,分支成本没有“一般情况”:它因芯片而异。

如果您碰巧知道一个值得注意的情况,即分支比缓存内间接更便宜(有或没有分支预测),请提及。

4

4 回答 4

5

这在很大程度上取决于具体情况。

1 缓存(L1、L2、L3)中的数据多久一次,或者必须多久从 RAM 中一直提取一次?

从 RAM 中提取大约需要 10-40ns。当然,这只会填满整个缓存行,所以如果你再使用接下来的几个字节,它肯定不会“受到严重伤害”。

2 它是什么处理器?

较旧的 Intel Pentium4 以其长流水线阶段而闻名,并且需要 25-30 个时钟周期(在 2GHz 时约为 15ns)才能从错误预测的分支中“恢复”。

3 这种情况有多“可预测”?

分支预测在现代处理器中确实有帮助,它们也可以很好地处理“不可预测”的分支,但它确实有点伤害。

4 缓存有多“忙”和“脏”?

如果您必须丢弃一些脏数据来填充缓存行,则在“获取数据”时间之外还需要 15-50ns。

间接寻址本身将是一条快速指令,但当然,如果下一条指令立即使用数据,您可能无法立即执行该指令 - 即使数据在 L1 缓存中。

另一方面,在美好的一天(很好的预测、缓存中的目标、正确方向的风等),分支需要 3-7 个周期。

最后,当然,编译器通常非常清楚什么最有效...... ;)

总而言之,很难肯定地说,唯一的方法来判断你的情况更好是对替代解决方案进行基准测试。我会认为间接内存访问比跳转更快,但是如果没有看到你的源代码编译成什么代码,很难说。

于 2013-01-10T00:40:19.520 回答
3

这真的取决于你的平台。不看目标 CPU 的内部,就没有一个正确的答案。我的建议是在测试应用程序中以两种方式测量它,看看是否有明显的差异。

我的直觉是,在现代 CPU 上,通过函数指针进行分支和条件分支都依赖于分支预测器的准确性,因此如果预测器具有相似的工作负载,我希望这两种技术具有相似的性能。(即,如果它总是以相同的方式结束分支,预计它会很快;如果难以预测,预计它会受到伤害。)但唯一确定的方法是在您的目标平台上运行一个真实的测试。

于 2013-01-10T00:30:40.080 回答
2

它取决于处理器到处理器,但取决于您正在使用的数据集,由错误预测的分支(或在某些情况下错误排序的指令)引起的管道刷新可能比简单的缓存未命中对速度的破坏更大。

例如,在 PowerPC 的情况下,未采用(但预计将采用)的分支花费大约 22 个周期(重新填充管道所花费的时间),而 L1 缓存未命中可能花费 600 个左右的内存周期。但是,如果您要访问连续数据,最好不要分支并让处理器缓存丢失您的数据,代价是为您的每组数据花费 3 个周期(预计会占用占用的分支)重新加工。

这一切都归结为:自己测试。对于所有问题,答案并不是确定的。

于 2013-01-10T00:45:26.297 回答
0

由于处理器必须预测条件答案以计划哪条指令有更多的机会被执行,我想说指令的实际成本并不重要。

条件指令效率低下,因为它们使流程变得不可预测。

于 2013-01-10T00:32:05.210 回答