Sun Studio 12: パフォーマンスアナライザ

コンパイラのコメント

コンパイラのコメントは、コンパイラによって最適化されたコードがどのように生成されたかを示します。インデックス行や元のソース行と区別できるように、コンパイラのコメント行は青く表示されます。コンパイラのさまざまな段階で、実行可能ファイルにコメントが挿入されることがあります。各コメントは、ソースの特定の行に関連付けられます。注釈付きソースの書き込み時には、ソース行に対してコンパイラが生成するコメントが、ソース行の直前に挿入されます。

コンパイラのコメントは、最適化するためにソースコードに対して行われた変換の大部分に関する情報を提供します。こうした変換には、ループの最適化、並列化、インライン化、パイプライン化などがあります。次に、コンパイラのコメントの例を示します。


                    関数 freegraph はソースファイル ptraliasstr.c から次の行へ
              インライン化されました
0.       0.         47.       freegraph();
                    48.    }
0.       0.         49.    for (j=0;j<ITER;j++) {

                    関数 initgraph はソースファイル ptraliasstr.c から次の行へ
                    インライン化されました
0.       0.         50.       initgraph(rows);
        
                    関数 setvalsmod はソースファイル ptraliasstr.c から次の行へ
                    インライン化されました
              以下のループは 2 個のループに分裂しました
              以下のループは 51 行目のループと融合しました
              以下のループは展開および/あるいは並列化の向上のため、
                             繰り返しを省略しました
              以下のループは定常サイクル数 = 3 でスケジュール化されました
              以下のループは 8 回、展開されました
              以下のループは繰り返しにつき 0 のロード、3 のストア、
                    3 の先読み、0 の FPadds、0 の FPmuls、0 の FPdivs を行います
                    51.       setvalsmod();

関数 setvalsmod() にはループコードが含まれており、この関数はインライン化されているため、51 行目のコメントにはループコメントが含まれています。

「ソース」タブに表示されるコンパイラコメントの種類は、「データ表示方法の設 定」ダイアログボックスの「ソース/逆アセンブリ」タブを使って設定できます。詳細は、「データ表示オプションの設定」を参照してください。

共通部分式の除去

非常に一般的な最適化の例として、1 つの式が複数の場所に存在するときに、この式のコードを 1 つの場所にまとめることによってパフォーマンスを向上できます。たとえば、コードブロックの ifelse の分岐の両方で同じ演算が記述されている場合、コンパイラはその演算を if 文の直前に移動することができます。実際にそのようにした場合、コンパイラは以前出現した一方の式に基づいて、命令に行番号を割り当てます。割り当てられた行番号が if 構造の分岐の 1 つに対応していて、実際にはもう一方の分岐が常に実行される場合、注釈付きソースでは、実行されない分岐内の行のメトリックが表示されます。

ループの最適化

コンパイラは、数種類のループ最適化を行うことができます。 一般的なものを次に示します。

ループの展開では、ループ本体内でループを数回反復し、それに応じてループインデックスを調整します。ループの本体が大きくなるほど、コンパイラはより効率的に命令をスケジュールできます。また、ループインデックスの増分や条件検査操作によるオーバーヘッドが減少します。残りのループは、ループのピーリングを使って処理されます。

ループのピーリングでは、ループから多数のループの反復を取り除き、これらをループの前か後ろに適宜移動します。

ループの入れ換えは、メモリーのストライドを最小限に抑えてキャッシュ行のヒット率を最大限に上げるために、入れ子のループの順序を変更します。

ループの融合は、隣り合ったループや近接したループを 1 つのループにまとめます。ループの融合からは、ループの展開と同じような利点がもたらされます。さらに、最適化済みの 2 つのループで共通のデータにアクセスする場合は、ループの融合によってループのキャッシュの局所性が改善されて、コンパイラは命令レベルの並列化機能をさらに活用することが可能になります。

ループの分散はループの融合の反対で、ループは複数のループに分割されます。この最適化は、ループ内の計算回数が過度に多くなり、パフォーマンス低下の原因となるレジスタのスピルが発生する場合に適しています。また、ループの分裂は、ループに条件文が含まれている場合にも有効です。場合によっては、条件文を含むものと含まないものの 2 つにループを分割できます。これによって、条件文を含まないループにおけるソフトウェアのパイプライン化の機会が増えます。

場合によって、入れ子のループでは、コンパイラはループの分裂を適用してループを分割し、次にループの融合を実行して異なる方法でループをまとめ直すことでパフォーマンスを改善します。この場合は、次のようなコンパイラのコメントが表示されます。


    以下のループは 2 個のループに分裂しました
    以下のループは 116 行目のループと融合しました
    [116]    for (i=0;i<nvtxs;i++) {

関数のインライン化

インライン関数を使用して、コンパイラは、実際の関数呼び出しを行う代わりに、関数が呼び出された場所に関数の命令を直接挿入します。つまり、C/C++ マクロと同様に、それぞれの呼び出し場所でインライン関数の命令の複製が作成されます。コンパイラは、高レベルの最適化 (4 および 5) で明示的または自動的なインライン化を実行します。インライン化によって関数呼び出しの負荷が減り、レジスタの使用や命令のスケジュールを最適化するための命令がさらに提供されますが、その代わりに、コードのメモリー使用量が多くなります。次に、コンパイラコメントのインライン化の例を示します。


                関数  initgraph はソースファイル ptralias.c から次の行の
                    コードへインライン化されました
0.       0.         44.       initgraph(rows);

注 –

コンパイラのコメントは、アナライザの「ソース」タブ内で 2 行にまたがって折り返されることはありません。


並列化

Sun、Cray、または OpenMP の並列化指令が含まれているコードの場合、複数プロセッサ上での並列実行用にコンパイルできます。コンパイラのコメントは、並列化が実行されている場所と実行されていない場所とその理由を示します。次に、並列化コンピュータのコメントの例を示します。


0.       6.324       9. c$omp  parallel do shared(a,b,c,n) private(i,j,k)
0.       0.    
                   以下のループは明示的なユーザー指令によって並列化されました
                   以下のループは 12 行目のループと交換されました
0.010    0.010     [10]            do i = 2, n-1

                   以下のループは並列化ループ中でネストされていたため、
                   並列化されていません
                   以下のループは 12 行目のループと交換されました
0.170    0.170      11.               do j = 2, i

並列実行とコンパイラ生成の本体関数の詳細は、「OpenMP ソフトウェアの実行の概要」を参照してください。