逻辑/关系表达式优化

时间:2013-02-25 15:52:30

标签: c++ c expression logical-operators relational

我需要优化表单的表达式:

(a > b) || (a > c)

我尝试了几种优化形式,其中一种如下:

(a * 2) > (b + c)

优化不是来自编译器的观点。我想将两个> s减少到一个。

这是基于1< =(a,b,c)< = 26

的假设

但是,这仅适用于某些情况。我正在努力做的优化,真的可能吗?如果是的话,开始会非常有帮助。

3 个答案:

答案 0 :(得分:4)

答案可能是:你不想优化它。而且,我怀疑有没有办法更有效地写这个。如果你说a,b和c是1到26之间的值,你不应该使用整数(你不需要那个精度),如果你想要最佳(大小)。

如果是> b,表达式a> c无论如何都不会被执行。因此,您最多有2个(并且至少1个)条件运算,这实际上不值得进行优化。

答案 1 :(得分:2)

我很怀疑这在大多数情况下甚至是优化。

 a > b || a > c 

将评估为:

 compare a b
 jump not greater
 compare a c
 jump not greater

其中

 a * 2 > b + c

给出:

 shift a left 1 (in temp1)
 add b to c (in temp2)
 compare temp1 temp2
 jump if not greater

与性能一样,基于实际性能测量(最好是选择处理器架构)的决策总是好得多。

答案 2 :(得分:1)

我能想到的最好的就是这个

char a, b, c;
std::cin >> a >> b >> c;

if (((b-a) | (c-a)) & 0x80) {
    // a > b || a > c
}

使用gcc -O2,这只生成一个条件分支

40072e:       29 c8                   sub    %ecx,%eax
400730:       29 ca                   sub    %ecx,%edx
400732:       09 d0                   or     %edx,%eax
400734:       a8 80                   test   $0x80,%al
400736:       74 17                   je     40074f <main+0x3f>

这会利用输入值的约束,因为值不能大于26,然后从a减去b会在a > b时给你一个负值,在两个补码中知道位7将在这种情况下设置 - 同样适用于c。然后我 OR 两者,以便位7指示a > b || a > c,最后我们通过 AND 检查位7和0x80并且分支这一点。

更新:出于好奇,我计划了4种不同的编码方式。为了生成测试数据,我使用了一个简单的线性同余伪随机数发生器。我将它定时循环1亿次迭代。为简单起见,我假设如果条件为真,我们想将5添加到计数器,否则不执行任何操作。我使用g++ (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)使用Intel Xeon X5570 @ 2.93GHz使用-O2优化级别时使用#include <iostream> unsigned myrand() { static unsigned x = 1; return (x = x * 1664525 + 1013904223); } int main() { size_t count = 0; for(size_t i=0; i<100000000; ++i ) { int a = 1 + myrand() % 26; int b = 1 + myrand() % 26; int c = 1 + myrand() % 26; count += 5 & (((b-a) | (c-a)) >> 31); // 0.635 sec //if (((b-a) | (c-a)) & 0x80) count += 5; // 0.660 sec //if (a > std::max(b,c)) count += 5; // 0.677 sec //if ( a > b || a > c) count += 5; // 1.164 sec } std::cout << count << std::endl; return 0; } 进行计时。

这是代码(注释掉除了一个条件变体之外的所有变量):

1s

最快的是对我的答案中的建议进行了修改,我们使用符号扩展来生成32 0s或32 5的掩码,具体取决于条件是否为false,并使用它来屏蔽正在添加的( a > b || a > c),以便它添加5或0.此变体没有分支。时间在每一行的评论中。最慢的是原始表达式{{1}}。