【发布时间】:2014-04-30 08:48:29
【问题描述】:
我想知道用 2 次乘法替换分支是否更快(由于缓存未命中惩罚)?
这是我的情况:
float dot = rib1.x*-dir.y + rib1.y*dir.x;
if(dot<0){
dir.x = -dir.x;
dir.y = -dir.y;
}
我正在尝试将其替换为:
float dot = rib1.x*-dir.y + rib1.y*dir.x;
int sgn = (dot < 0.0) - (0.0 < dot ); //returns -1 or 1 (no branching here, tested)
dir.x *= sgn;
dir.y *= sgn;
【问题讨论】:
-
您为什么不对其进行基准测试并告诉我们您发现了什么?
-
我担心在我的带有 8Mb 缓存的 i7 上,我永远不会在这个测试中出现缓存未命中。
-
如果它不会发生,那有什么关系呢? ;) 我假设您想针对具有较小缓存的内核来证明这一点?为什么不简单地用海量数据集进行测试,比你的 i7 处理的还要大?
-
分支的问题不在于缓存未命中,而在于中断instruction pipeline。而且,顺便说一句,当它说“8Mb”的缓存时,那是 L3 缓存,它只是引用总容量,而缓存未命中与通常约为 64 字节的 缓存行 相关(至少,在 i7 上是)。
-
顺便说一下,全球 50% 的概率不提供可预测性信息。可以很好地预测 20 次被录取,然后 20 次未被录取(通常为 90%)。使用“循环”预测器,如果分支始终在采用和未采用之间交替(即 T,NT,T,NT,T,NT,...),预测将接近 100%。我宁愿怀疑 FP 条件移动会比你的整数评估和 FP 乘法更快。一些 SIMD 指令集还提供比较,如果为真,则设置数据元素中的所有位,左移 32 位和异或将(我相信)有条件地否定。
标签: c++ performance cpu cpu-cache branch-prediction