-a 和 0-a 有什么区别?
資深大佬 : nyanyh 13
认识的一位技术人员告诉我用 0-a 替换-a,可以提升性能,我将信将疑,写了小代码测试一下
int main() { int a = 100; auto a1 = -a; auto a2 = 0-a; return 0; }
然后看看 LLVM 的中间码
%6:gr32 = SUB32rm %0:gr32(tied-def 0), %stack.1, 1, $noreg, 0, $noreg, implicit-def $eflags, debug-location !19 :: (load 4 from %ir.2); ./test.cpp:5:15 MOV32mr %stack.2, 1, $noreg, 0, $noreg, killed %6:gr32, debug-location !17 :: (store 4 into %ir.3); ./test.cpp:5:10 %3:gr32 = SUB32rm %0:gr32(tied-def 0), %stack.1, 1, $noreg, 0, $noreg, implicit-def $eflags, debug-location !23 :: (load 4 from %ir.2); ./test.cpp:6:16 MOV32mr %stack.3, 1, $noreg, 0, $noreg, killed %3:gr32, debug-location !21 :: (store 4 into %ir.4); ./test.cpp:6:10
是完全一样的
再试试如果 a 是 double 呢?
int main() { double a = 100; auto a1 = -a; auto a2 = 0-a; return 0; }
出现了明显不同:
%11:fr64 = MOVSDrm_alt %stack.1, 1, $noreg, 0, $noreg, debug-location !19 :: (load 8 from %ir.2); ./test.cpp:5:16 %7:gr64 = MOVSDto64rr killed %11:fr64, debug-location !20; ./test.cpp:5:15 %8:gr64 = MOV64ri -9223372036854775808, debug-location !20; ./test.cpp:5:15 %9:gr64 = XOR64rr killed %7:gr64(tied-def 0), %8:gr64, implicit-def $eflags, debug-location !20; ./test.cpp:5:15 %10:fr64 = MOV64toSDrr killed %9:gr64, debug-location !20; ./test.cpp:5:15 MOVSDmr %stack.2, 1, $noreg, 0, $noreg, killed %10:fr64, debug-location !18 :: (store 8 into %ir.3); ./test.cpp:5:10 %2:fr64 = FsFLD0SD debug-location !24; ./test.cpp:6:16 %4:fr64 = SUBSDrm %2:fr64(tied-def 0), %stack.1, 1, $noreg, 0, $noreg, debug-location !24 :: (load 8 from %ir.2); ./test.cpp:6:16 MOVSDmr %stack.3, 1, $noreg, 0, $noreg, killed %4:fr64, debug-location !22 :: (store 8 into %ir.4); ./test.cpp:6:10 $eax = COPY %0:gr32, debug-location !25; ./test.cpp:8:5
上面的代码都是用-O0测试的,打开优化的话就测试不出了,两行代码直接被优化掉了
所以在某些情况下确实 0-a 比-a 少几条指令,所以会快一些?
大佬有話說 (5)