这是一篇很好的文章,讲述了低级优化技术,并展示了一个例子,作者将昂贵的部门转换为便宜的比较。 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倍加速所致。
虽然比较非常便宜,但我一直听说分支机构非常昂贵,因为它们可能会导致管道堵塞。由于关于分支的传统观点,我从来不会考虑这种方法。
为什么在这种情况下分支不是瓶颈?是因为我们在每次比较之后都会返回吗?是否因为这里的代码大小很小,因此处理器没有太多预测误差?在什么情况下它会成为瓶颈,并开始主宰分裂的成本?作者从来没有谈论过这件事。
任何人都可以解决便宜的比较和昂贵的分支机构之间的明显争用?当然,优化的黄金法则是必须始终衡量。然而,至少对这个问题有一些直觉是很好的,以便在尝试提出更快速地制作代码的新方法时可以智能地进行比较。
谢谢!
呃。它正在减少分支。 'if'是一个分支,但'while'也有一个分支。现在这些人数减少了4倍。在简单的情况下,它只是重新排序分支,并减少div /增量操作。在实际情况下(使用分支预测?)它将允许管道保持填充状态,因为条件不是_actually_分支,而“while”总是分支 – sehe
“条件实际上并不分支”是什么意思? “ if(v <10) 确实看起来像一个分支给我。 –
根据生成的程序集,其中一个“分支”不会实际分支(EIP只会像增加一个noop一样增加) – sehe