Skip to content
败犬日报 2025-09-22

败犬日报 2025-09-22

1. 锐评 if (flag) { res = 0.0; }res = static_cast<double>(!flag) * res;

起因是群友同事不好好写代码,把 if (flag) { res = 0.0; } 写成 res = static_cast<double>(!flag) * res;

简单来说就是可读性优先,选择第一种或者三目 res = flag ? 0 : res; 都可以接受。功能上如果 res = inf / nan 乘法会寄。虽然有分支,但是性能不会有很大差别,没必要抠这点性能。

过早的优化是万恶之源。—— Donald Knuth, 1974


虽然没必要抠性能,但架不住很有意思啊。

我们知道分支惩罚是大概 15-20 个 CPU 周期,常见 CPU double 乘法的 latency 是 4 个,分支命中率至少 75% 才能性能接近。这就取决于程序是否分支友好(例如矩阵乘能有很高的命中率,而排序就不行)。

这里可能有人要说,三目运算符不是可以优化为 cmov 吗,为什么还有分支。这就不得不提 x86 cmov 只支持通用寄存器。

虽然 sse 有 blend 指令可以替代,也可以 mov 到通用寄存器 cmov,但是试了一下编译器(GCC)似乎强烈地倾向于使用分支。即使我手动写了 std::bit_cast,以及其他很多方法都不行,只有手动写 sse 内置函数和内嵌汇编可以。这块我打算另写一个文章,可以期待一下。(文章已完成 https://zhuanlan.zhihu.com/p/1958574956985156706