この章では、プログラムのパフォーマンスの測定と表示方法を説明します。プログラムがどこでその計算サイクルをもっとも費やしているか、またどのような効率でシステム資源を使用しているかを知ることが、パフォーマンスのチューニングの前提条件となります。
ハイパフォーマンスのアプリケーションを開発するには、コンパイラ機能を組み合わせたり、最適化されたルーチンのライブラリ、パフォーマンス解析のためのツールが必要です。
Sun Studio ソフトウェアでは、プログラムのパフォーマンスデータを収集し、分析するための高度なツールが提供されています。
コレクタは、プロファイリングとよばれる統計ベースでパフォーマンスデータを収集します。 そのデータには、呼び出しスタックの統計プロファイル、スレッド同期遅延イベント、ハードウェアカウンタのオーバーフロープロファイル、アドレス空間データ、およびオぺレーティングシステムの要約情報を含めることができます。
パフォーマンスアナライザは、ユーザーが情報を調査できるように、標本コレクタにより記録されたデータを表示します。 アナライザはデータを処理し、関数、呼び出し元 - 呼び出し先、ソース行、分解指示、プログラムのレベルでさまざまなパフォーマンスメトリックを表示します。これらのメトリックは、次の 3 つのグループに分類されます。時間ベースの測定基準、同期遅延測定基準、およびハードウェアカウンタ測定基準です。
また、パフォーマンスアナライザを使用すれば、アプリケーションのアドレス空間での関数のロード順序を改善するためのマップファイルを作成することで、アプリケーションのパフォーマンスを細かく調整できます。
これら 2 つのツールは、次のような質問に答えるのに役立ちます。
プログラムが使用するリソースはどれくらいですか?
リソースの大部分を使用するのはどの関数またはロードオブジェクトですか?
リソースの大部分を使用するのはどのソース行や逆アセンブリ命令ですか?
プログラムはどのようにして実行時の現在のポイントに達しますか?
関数やロードオブジェクトによってどのリソースが使用されていますか?
パフォーマンスアナライザのメインウィンドウは、各関数の排他的および組み込みメトリック (計測データ) を持つプログラムの関数リストを表示します。リストは、ロードオブジェクト、スレッド、軽量プロセス (LWP) およびタイムスライスによりフィルタ処理できます。選択された関数に対し、subsidiary ウィンドウは関数の呼び出し先と呼び出し元を表示します。このウィンドウは呼び出しツリーを操作するのに使用できます。 たとえば、高いメトリック値の検索などです。さらに 2 つのウィンドウが、行ごとにパフォーマンスメトリックの注釈付きのソースコードや、コンパイラコメントでインタリーブされたソースコード、各命令にメトリックの注釈付きの逆アセンブリコードを表示します。ソースコードやコンパイラコメントは、可能な場合に、命令によりインタリーブされます。
ソフトウェア開発者にとってパフォーマンスのチューニングが主な仕事でないとしても、コレクタとアナライザはソフトウェア開発者向けに設計されています。これらは、一般的に使用されているプロファイルツール prof と gprof より柔軟性のある、詳細で正確な解析を提供し、gprof の属性エラーに依存しません。
使用可能なコレクタとアナライザのコマンド行等価ユーティリティーは、次のとおりです。
collect (1) コマンドを使用して、データ収集を行うことができます。
collector サブコマンドを使用して、データ収集を dbx から実行できます。
コマンド行ユーティリティーの er_print (1) は、さまざまなアナライザ表示の ASCII バージョンを出力します。
コマンド行ユーティリティー er_src (1) はソースおよび逆アセンブリコードリストをコンパイラのコメント付きで、パフォーマンスデータなしで表示します。
詳細については、Sun Studio のマニュアル『プログラムのパフォーマンス解析』を 参照してください。
プログラムのパフォーマンスと資源の利用状況に関する基本的なデータを収集するには、time (1) コマンドを使用するか、または、csh で set time コマンドを発行するのがもっとも簡単な方法です。
time コマンドでプログラムを実行すると、プログラム終了時に時間情報行が出力されます。
demo% time myprog 答えは: 543.01 6.5u 17.1s 1:16 31% 11+21k 354+210io 135pf+0w demo% |
各欄の意味は次のとおりです。
ユーザー - システム - 時計時間 - 資源 - メモリー - 入出力 - ページング
6.5u 17.1s 1:16 31% 11+21k 354+210io 135pf+0w |
システム– このタスクのシステムコード中で約 17.1 秒
時計時間– 実行完了までに 1 分 16 秒
資源– このプログラムのために使用されたシステム資源は 31 %
メモリー– 共有プログラムメモリーは 11K バイト、プライベートデータメモリーは 21K バイト
入出力– 読み取りは 354 回、書き込みは 210 回
ページング– ページフォルトは 135 回、スワップアウトは 0 回
プログラムがマルチプロセッサ環境で並列に実行されたとき、結果の時間の解釈方法は異なります。/bin/time はユーザー時間を異なるスレッドで累積するので、実測時間だけが使用されます。
表示されるユーザー時間にはすべてのプロセッサ上で費やされた時間が含まれるので、かなり大きくなり、パフォーマンスの測定方法としては適していません。より適している測定は実時間、つまり、実測時間です。これは、並列化されたプログラムの正確な時間を得るには、ユーザーのプログラムだけに専念するシステム上で実行しなければならないということも意味します。
tcov(1) コマンドは、-xprofile=tcov オプションを付けてコンパイルしたプログラムとともに使用すると、どの文がどれくらい実行されたかを示す、ソースコードの文ごとのプロファイルを生成します。また、プログラムの基本ブロック構造に関する情報の要約も提供します。
拡張された文レベルのカバレージは、-xprofile=tcov コンパイラオプションと tcov -x オプションによって呼び出されます。出力はソースファイルのコピーであり、各文のマージンに実行回数が注釈されています。
tcov により生成されたコード適用範囲レポートは、コンパイラがルーチン呼び出しをインライン化した場合は信頼性が低くなります。コンパイラは、最適化レベルが -O3 以上で -inline オプションが指定されている場合は呼び出しをインライン化します。それにより、コンパイラはルーチンへの呼び出しを呼び出し先ルーチンの実コードに置き換えます。このとき、呼び出しがないので、これらのインライン化されたルーチンへの参照は tcov により報告されません。そのため正しい適用範囲レポートを取得するには、コンパイラのインライン化機能を有効にしてはいけません。
tcov を使用するには、 -xprofile=tcov を付けてコンパイルします。プログラムを実行するとき、カバレージデータは program.profile/tcovd に格納されます。program は実行可能ファイルの名前です。実行可能ファイルが a.out の場合、a.out.profile/tcovd が作成されます。
tcov -x dirname source_files を実行して、ソースファイルごとにマージされたカバレージ解析を作成します。レポートは、現在のディレクトリにある file.tcov に書き込まれます。
簡単な例を実行します。
demo% f95 -o onetwo -xprofile=tcov one.f two.f demo% onetwo ... プログラムからの出力が表示される demo% tcov -x onetwo.profile one.f two.f demo% cat one.f.tcov two.f.tcov program one 1 -> do i=1,10 10 -> call two(i) end do 1 -> end .....etc demo% |
環境変数 $SUN_PROFDATA と $SUN_PROFDATA_DIR を使用すると、中間データ収集ファイルが格納される場所を指定できます。中間データ収集ファイルは *.d と tcovd ファイルで、それぞれ古いスタイルの tcov と新しいスタイルの tcov によって作成されます。
これらの環境変数を使用して、異なる実行から収集されたデータを分けることができます。これらの環境変数を設定すると、実行プログラムは実行データを $SUN_PROFDATA_DIR/$SUN_PROFDATA/ 中のファイルに書き込みます。
同様に、tcov が読み出すディレクトリは、tcov -x $SUN_PROFDATA で指定されます。$SUN_PROFDATA_DIR が設定された場合、tcov はそれを前に付けて、作業中のディレクトリではなく、$SUN_PROFDATA_DIR/$SUN_PROFDATA/ 中でファイルを探します。
それぞれ、このあとの実行のたびに tcovd ファイルに、さらにデータが追加されます。各オブジェクトファイルのデータは、ソースファイルが再コンパイルされたあとにプログラムがはじめて実行されるときにクリアされます。プログラム全体のデータは、tcovd ファイルを削除したときにクリアされます。
詳細は、tcov(1) のマニュアルページを参照してください。