最近我意识到我已经做了太多的分支而没有关心它对性能的负面影响,因此我决定尝试学习所有关于不分支的知识。这是一个更极端的情况,试图使代码尽可能少的分支。
因此对于代码
if(expression)
A = C; //A and C have to be the same type here obviously
表达式可以是A == B,或者Q< = B,它可以是任何解析为true或false的东西,或者我想在结果为1或0时将其视为
我已经提出了这个非分支版本
A += (expression)*(C-A); //Edited with thanks
所以我的问题是,这是一个能够最大限度提高效率的好解决方案吗? 如果是,为什么,如果不是为什么?
答案 0 :(得分:6)
取决于编译器,指令集,优化器等。当您使用布尔表达式作为int
值时,例如(A == B) * C
,编译器必须进行比较,并设置一些根据结果注册为0或1。除了分支之外,某些指令集可能没有任何方法可以做到这一点。一般来说,最好编写简单,直接的代码,让优化程序弄清楚,或者找到一个分支较少的不同算法。
答案 1 :(得分:2)
Jeez,不,不要那样做!
任何“惩罚[你] [你]很多分支”的人都会希望让你打包使用那些糟糕的东西。
这怎么可怕,让我算上一些方法:
C
)乘以布尔值(例如,(A==B)
会产生{{1 }或true
)。有些语言会,有些则不会。答案 2 :(得分:0)
如果您已经分析了程序的运行时属性并确定此处存在频繁的分支错误预测,并且这导致了实际性能问题,那么您应该只考虑这样做。它使代码变得不那么清晰,而且一般来说它的速度会更快(在你感兴趣的情况下,这也是你需要测量的东西)。
答案 3 :(得分:0)
经过研究,我得出的结论是,当存在瓶颈时,最好包含定时分析器,因为这些代码通常不可移植,主要用于优化。
我在阅读下面的以下问题后得到了一个确切的例子
Why is it faster to process a sorted array than an unsorted array?
我使用它在C ++上测试了我的代码,由于额外的算术,我的实现实际上更慢。
无论其! 对于下面这种情况
if(expression) //branched version
A += C;
//OR
A += (expression)*(C); //non-branching version
时机就是这样。 分支排序列表大约是2秒。
分支未分类列表大约10秒钟。
我的实现(无论是排序的还是未排序的)都是3秒。
这表明在一个未排序的瓶颈区域,当我们有一个简单的分支时,可以简单地用一个乘法代替。
考虑我建议的实施可能更值得。 **再次主要是针对被视为瓶颈的区域**