与其他任何数字相比,比零快吗?

时间:2014-03-17 21:44:14

标签: c++ optimization compare zero

if(!test)

if(test==-1)

我可以生产组装但​​是组装太多了,我无法找到我追求的细节。我希望有人知道答案。我猜它们是相同的,除非大多数CPU架构都有某种“比较为零”的捷径。

感谢您的帮助。

3 个答案:

答案 0 :(得分:7)

通常,是的。在典型的处理器中测试零或测试符号(负/正)是简单的条件代码检查。这意味着可以重新排序指令以省略测试指令。在伪装配中,请考虑:

Loop:
  LOADCC r1, test // load test into register 1, and set condition codes
  BCZS   Loop     // If zero was set, go to Loop

现在考虑对1进行测试:

Loop:
  LOAD   r1, test // load test into register 1
  SUBT   r1, 1    // Subtract Test instruction, with destination suppressed
  BCNE   Loop     // If not equal to 1, go to Loop

现在通常的预优化免责声明:你的程序太慢了吗?不要优化,分析它。

答案 1 :(得分:3)

这取决于。

当然它依赖于,并非所有架构都相同,并非所有μarch都相等,即使编译器不相等,但我会假设它们以合理的方式编译它。

假设平台是32位x86,程序集可能看起来像

test eax, eax
jnz skip

Vs的:

cmp eax, -1
jnz skip

那有什么区别?不多。第一个片段减少了一个字节。第二个片段可以用inc实现,以缩短它,但这会使它具有破坏性,因此它并不总是适用,而且无论如何,它可能更慢(但又取决于它)。

采用任何现代英特尔CPU。他们进行“宏观融合”,这意味着他们采取比较和分支(受到一些限制),并融合它们。在大多数情况下,比较基本上是免费的。 test也是如此。但不是inc,但inc技巧首先才真正应用,因为我们碰巧比较为-1。

除了任何“奇怪的效果”(由于更改的对齐和诸如此类),在该平台上应该没有任何区别。差别不大。

即使你很幸运并且因为之前的算术指令而免费获得test,它仍然不会更好。

当然,在其他平台上会有所不同。

答案 2 :(得分:3)

在x86上没有任何显着差异,除非你同时做一些数学运算(例如while(--x) --x的结果将自动设置条件代码,其中{ {1}}必须对while(x) ...中的值进行某种测试才能知道它是否为零。

许多其他处理器确实在LOAD或MOVE指令"上自动更新条件代码,这意味着检查" postive"," negative"和"零"是"免费"随着数据的每一次移动。当然,你不能通过分支指令向后传播比较指令来支付费用,所以如果你有比较,下一条指令必须是条件分支 - 这些指令之间的额外指令可能有助于缓解任何延迟的结果"从这样的指示。

一般来说,这些微优化最好留给编译器而不是用户 - 如果编译器认为有意义的话,编译器通常会将x转换为for(i = 0; i < 1000; i++) [和顺序在编译器的视图中,循环的重要性并不重要。试图聪明地使用这些东西往往会使代码变得不可读,并且性能在其他系统上会受到严重影响(因为当你开始调整&#34;自然&#34;代码到#34;不自然&#34;时,编译器倾向于认为你真正的意思是你写的,而不是像&#34;自然&#34;版本那样优化它。