Bit manipulation to replace IF statement and improve performance
我可以替换以下if语句:
1 2 3 | if(condition){ x += y; } |
用:
1 | x = x + ((y - x) * (condition)); |
移除分支。
有没有一种方法可以避免上面的乘法运算,并用逐位操作替换它以使其更快?
在没有用预期的用法测量应用程序之前,不要这样做。
为什么不。现代的编译器已经可以检测到这些模式并将其转换为条件移动。
现代CPU推测性地在"时间之前"运行代码,这可能比复杂的位表达式更快;此外,还有一个分支目标缓冲区,它在本地循环中记住决策,然后根据BTB推测性地提前运行代码。
如前所述:不要在没有使用预期用途测量应用程序的情况下执行此操作。不要在任意的基准上进行测试,因为这些基准在大多数情况下都会产生误导性(因此成本高昂)的结果。当然,更喜欢算法和架构优化,而不是这种微优化;从长远来看,保持代码可维护性通常更便宜;不要基于未定义的行为和高度专业化的代码构建业务:
也。你是C或C++向导足以验证你的"优化"的正确性吗?您是否考虑了无符号溢出和未定义的行为w.r.t.有符号溢出?类型促销?
我认为答案是否定的,因为你寻求帮助,但是没有意识到在你的例子中使用的类型是关键的,但是没有提到。
这种优化实际上不会提高您的性能。编译器在优化代码方面做得比用这么便宜的技巧好得多。在这种情况下,您实际上会增加代码的复杂性,从而降低代码的效率。必须始终执行乘法和加法。
1 2 3 | if(condition){ x += y; } |
是
1 2 3 | if(condition){ x =x+ y; } |
所以你可以把它写成,
1 | x = x + ((y) * (condition)); |
仅当条件为
1 | x = x + ((y - x) * (condition)); |
即使条件只导致
1 2 3 | if(condition){ x=y; } |
不知道你能不能打败整数乘法。在某些处理器上需要一个时钟。
假设条件为0/1:
1 | x+= condition * y; |
可选地:
1 | x+= (- condition) & y; |
在进行任何评估之前,您应该为每个变量添加类型。人们可能有不同的假设。另外,我的建议是不要这样做。即使你现在做对了,维护它也会变成一场噩梦。
让它变为一个位,将它向上移动到符号位,然后用符号扩展将它向下移动,这样就可以得到全部1或全部0。
1 | x + (( y -x) & (((!!condition)<<31)>>31) |
不过,这取决于平台。