我有以下代码:
for(auto i =0;i<k;++i)
printf("%d\n",(va1+va2-(va1-va2))[i]);
其中va1
和va2
是两个valarray<int>
个对象,k
的大小为va1
和va2
。我期待的是编译器优化printf
行,如:
printf("%d\n", 2*va2[i]);
但是,英特尔编译器(13.1)和CLang(3.4)都没有进行这样的优化。例如,英特尔编译器输出汇编代码:
..B1.18: # Preds ..B1.19 ..B1.17
movl (%r14,%r15,4), %r9d #18.42
movl $.L_2__STRING.1, %edi #18.9
movl (%r12,%r15,4), %r8d #18.42
xorl %eax, %eax #18.9
lea (%r9,%r8), %esi #18.9
subl %r8d, %r9d #18.9
subl %r9d, %esi #18.9
..___tag_value_main.18: #18.9
call printf #18.9
..___tag_value_main.19: #
# LOE rbx r12 r13 r14 r15
..B1.19: # Preds ..B1.18
incq %r15 #17.25
cmpq %r13, %r15 #17.21
jl ..B1.18 # Prob 82% #17.21
其中r13
存储k
的值,r14
和r12
分别是va1
和va2
的内存开头。 r15
是迭代器变量i
。从代码中,它的作用是:
load va1[i]
load va2[i]
add va1[i], va2[i] ==> %esi
sub va1[i], va2[i] ==> %r9d
sub %esi, %r9d ==> esi
print %esi
为什么没有优化(即使使用-O3)
load va2[i]
add va2[i], va2[i] => %esi
print %esi
用窥视孔优化? Gcc 4.8.2在这种情况下进行优化,但无法处理-(va1[i]+va2[i])+(va1[i]-va2[i])
。
看起来一个可能的原因是表达模板在前面显示的代码中使用。现在问题是,为什么编译器在完美之前只停止优化一步?表达式模板如何阻止前进?
注意 的 好吧,答案总是“因为编译器不是为了进行优化而设计的”。但据我从龙书中了解到,编译器应该迭代地进行优化,直到它无法做得更好。