这是一篇很棒的文章,它讨论了低级优化技术,并展示了一个作者将昂贵的除法转换为便宜的比较的例子。 https://www.facebook.com/notes/facebook-engineering/three-optimization-tips-for-c/10151361643253920
对于那些不想点击的人,基本上他转换了这个:
uint32_t digits10(uint64_t v) {
uint32_t result = 0;
do {
++result;
v /= 10;
} while (v);
return result;
}
进入这个:
uint32_t digits10(uint64_t v) {
uint32_t result = 1;
for (;;) {
if (v < 10) return result;
if (v < 100) return result + 1;
if (v < 1000) return result + 2;
if (v < 10000) return result + 3;
// Skip ahead by 4 orders of magnitude
v /= 10000U;
result += 4;
}
}
导致高达 6 倍的加速。
虽然比较非常便宜,但我一直听说分支非常昂贵,因为它们会导致管道停顿。由于关于分支的传统智慧,我永远不会考虑这样的方法。
为什么在这种情况下分支不是瓶颈?是因为我们在每次比较之后立即返回吗?是因为这里的代码很小,因此处理器不会有太多的错误预测吗?在什么情况下它会成为瓶颈并开始主导部门的成本?作者从不谈论这个。
谁能解决廉价比较和昂贵分支之间的明显争论?当然,优化的黄金法则是必须始终衡量。但是,至少对这个问题有一些直觉是很好的,这样人们就可以在尝试提出使代码更快的新方法时智能地使用比较。
谢谢!