【发布时间】:2016-08-09 17:35:05
【问题描述】:
我有以下功能:
char f1( int a, unsigned b ) { return abs(a) <= b; }
为了执行速度,我想改写如下:
char f2( int a, unsigned b ) { return (unsigned)(a+b) <= 2*b; } // redundant cast
或者使用这个签名,即使对于非负的b 也可能产生微妙的影响:
char f3( int a, int b ) { return (unsigned)(a+b) <= 2*b; }
这两种选择都可以在一个平台上进行简单的测试,但我需要它是可移植的。假设非负 b 并且没有溢出风险,这是典型硬件和 C 编译器的有效优化吗?它对 C++ 也有效吗?
注意:作为带有-O3 的 gcc 4.8 x86_64 上的 C++,f1() 使用 6 个机器指令,f2() 使用 4 个。f3() 的指令与 f2() 的指令相同。同样有趣的是:如果 b 以文字形式给出,则两个函数都编译为 3 条指令,这些指令直接映射到 f2() 中指定的操作。
【问题讨论】:
-
为什么你认为这个实现会更优化?您是否检查过编译器实际发出的内容?
-
无论如何,演员阵容完全是多余的。
-
a*a <= b*b- 没有分支..溢出危险,虽然 -
@BaummitAugen:由于测试了多个场景,我在这里犯了一个错误。演员 是多余的,因为这是最初发布的,因为它是基于
b的类型为unsigned的隐式。我应该将b保留为int类型,现在将进行编辑。 -
您是否检查过 6 指令实际上比 4 指令慢?情况并非总是如此。
标签: c++ c language-lawyer undefined-behavior micro-optimization