2

私は以下にリストされたコードを持っています:

for(auto i =0;i<k;++i)                                                         
    printf("%d\n",(va1+va2-(va1-va2))[i]);    

ここでva1、 とva2は 2 つのvalarray<int>オブジェクトで、はとkのサイズです。私が期待しているのは、コンパイラが次のように行を最適化することです。va1va2printf

printf("%d\n", 2*va2[i]);

しかし代わりに、Intel コンパイラ (13.1) と CLang (3.4) の両方がそのような最適化を行いませんでした。たとえば、Intel コンパイラは次のアセンブリ コードを出力しました。

..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、 の値を格納しkr14およびはそれぞれおよびr12のメモリの先頭です。はイテレータ変数です。コードから、それが行うことは次のとおりです。va1va2r15i

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])

考えられる理由の 1 つは、前述のコードで式テンプレートが使用されていることです。問題は、なぜコンパイラは最適化を 1 段階手前で停止したのかということです。式テンプレートはどのようにして前進を妨げましたか?

ええと、答えは常に「コンパイラがその最適化を行うように設計されていないため」です。しかし、私がドラゴンブックから学んだ限りでは、コンパイラは、何も改善できなくなるまで最適化を繰り返し行う必要があります。

4

0 に答える 0