时
if(!test)
比
快if(test==-1)
我可以生产组装但是组装太多了,我无法找到我追求的细节。我希望有人知道答案。我猜它们是相同的,除非大多数CPU架构都有某种“比较为零”的捷径。
感谢您的帮助。
答案 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;版本那样优化它。