実行モニターのプロファイリング情報は、Oracle Developer Studio パフォーマンス分析ツールとその基盤となるオペレーティングシステムを使用して収集されます。実行モニターのツールは情報をグラフィカルに表示し、またクリックするとコードの問題領域に関する詳細情報を表示するボタンがあります。このセクションでは、プロファイリングデモプロジェクトの設定、プロジェクトのプロパティーでのプロファイルツールの有効化、および実行モニターのプロファイリングツールの実行結果の確認します。
このチュートリアルでは、ProfilingDemo サンプルプロジェクトを使用します。このデモを作成するには、次の手順に従います。
「ファイル」>「新規プロジェクト」(Ctrl+Shift+N) を選択します。
新規プロジェクトウィザードで、「サンプル」ノードを展開して、「C/C++」カテゴリを選択します。
「プロファイリングのデモ」プロジェクトを選択します。「次へ」をクリックして、「完了」をクリックします。
プロジェクトを構成してプロファイリングを有効にするには、次の手順に従います。
「プロジェクト」タブの「ProfilingDemo_1」プロジェクトノードを右クリックし、「プロパティー」を選択します。
「カテゴリ」パネルで「構築」ノードを選択し、「ツールコレクション」が Oracle Developer Studio に設定されていることを確認してください。
「カテゴリ」パネルで「実行」ノードを選択し、「コンソールタイプ」が「内部ターミナル」に設定されていることを確認してください。このチュートリアルで示すように、外部ターミナルのウィンドウではなく IDE の出力ウィンドウにプログラムの出力を表示できます。
「カテゴリ」パネルで「プロファイル」ノードを選択します。「実行時にプロファイリングインジケータを表示」オプションがチェックされていることを確認します。プロジェクトでこのオプションをチェックすると、実行モニターツールタブが表示されます。
「プロファイル構成」の「C/C++ Oracle Developer Studio 標準」を選択します。「プロファイル構成」リストの横にある「...」ボタンをクリックします。
「C/C++ Oracle Developer Studio 標準」で選択されているツールは、「スレッド使用量」、「メモリー使用」、および「CPU 使用率」であることを確認します。
「プロジェクトのプロパティー」ダイアログボックスで「OK」をクリックします。
ProfilingDemo_1 プロジェクトを構築および実行するには、次の手順に従います。
ProfilingDemo_1 プロジェクトノードを右クリックし、「構築」を選択します。
「出力」ウィンドウには、構築結果が表示されます。
ProfilingDemo_1 プロジェクトノードを右クリックし、「実行」を選択します。「実行モニター」ウィンドウが開き、「CPU 使用率」、「メモリー使用」、「スレッド使用量」の各インジケータと動的グラフが表示されます。
ProfilingDemo_1 プログラムの出力ウィンドウに実行中の処理が表示されるので、IDE によりツールにグラフィカルに表示されているデータと照合できます。たとえば、プログラムで割り当て中のメモリー量が表示され、計算が実行され、メモリーが解放されます。こうした動作がグラフに反映されるところを確認できます。
プログラムが終了するまで、リクエストされるたびに Enter を押します。
マウスカーソルをインジケータの上に置くと、各グラフについて説明するツールチップが表示されます。各インジケータには、詳細情報を表示するためのボタンがあります (ボタンについては後のセクションで説明します)。
「実行モニター」ウィンドウの下部には、グラフの表示を制御するための表示スライダ、詳細スライダおよびタイムスライダの各スライダがあります。これらのコントロールはデータのフィルタリングにも使用されます。次の図はコントロールの名前を示します。
スライダに関する情報を表示するには、マウスカーソルをスライダの終了ポイントの上に置きます。
タイムスライダ (下部の水平スクロール バー) でマウスボタンをクリックしたままにします。すべてのグラフが連動してスライドするため、任意の時点での CPU、メモリー、スレッドの状態を確認し、それらの関係を把握できます。
タイムスライダを左から右にドラッグすると、実行の全体を確認できます。
マウスを表示スライダ (時間単位で重なったコントロール) に合わせます。表示スライダは、実行時間のどの部分をグラフに表示するかを制御します。
表示スライダの開始ポイントのハンドルをクリックし、実行の開始位置までドラッグします。インジケータに実行全体が表示されます。この効果はズームアウトに似ています。すでにすべてのデータを表示しているため、時実行時間全体を選択すると、時間スクロールバーが最大化されることに注意してください。
表示スライダの開始ポイントを、PTHREAD_MUTEX_DEMO の開始位置にドラッグします。ハンドルをドラッグすると、インジケータはこの領域にフォーカスするようにズームインします。スクロールバーを使用してふたたび実行時間を前後にスクロールできるようになっていることに注意してください。
オレンジ色の詳細スライダの終了ポイントの上にマウスカーソルを合わせると、スライダの使用方法の説明が表示されます。詳細スライダコントロールを使用すると、実行時の特定の部分を選択し、詳細情報を確認できます。
詳細スライダの開始ポイントハンドルを、表示スライダの開始ポイントよりも後の時点にドラッグします。表示スライダの開始ポイント以降の領域がインジケータによってグレー表示になることを確認します。これにより、グラフの開始ポイントから終了ポイントまでの間の結果が強調表示されます。インジケータの詳細ボタンをクリックすると、詳細タブに、強調表示されている領域のデータが表示されます。
詳細スライダの開始ポイントをドラッグして開始位置まで戻し、すべてのデータを表示します。
「CPU 使用 (CPU Usage)」グラフには、アプリケーションの実行中に使用される合計 CPU 時間がパーセントで表示されます。
「CPU 使用率」の「ホットスポット...」ボタンをクリックし、CPU時間の詳細を表示します。
「関数あたりの CPU 時間」ウィンドウが開き、プログラムの関数が、各関数によって使用された CPU の時間とともに表示されます。関数は使用された CPU 時間の順に一覧表示され、使用時間がもっとも長い関数が最初に表示されます。プログラムがまだ実行中の場合、初期状態で表示される時間は、グラフをクリックした時点で消費された時間です。
「関数名」列見出しをクリックし、関数をアルファベット順にソートします。
CPU 時間の 2 つの列の違いを確認します。「CPU 時間 (包括的)」には、関数の実行開始から終了までの間に使用された CPU 時間の合計 (一覧表示された関数によって呼び出されたその他すべての関数の時間も含む) が表示されます。「CPU 時間 (排他的) (CPU Time (Exclusive))」には、特定の関数のみに使用された時間が表示され、その関数から呼び出された関数は含まれません。
「CPU 時間 (包括的)」列見出しをクリックして、使用時間がもっとも長い関数を先頭に戻します。
この例では work_run_usrcpu() 関数の CPU 時間 (排他的) が 613.079、CPU 時間 (包括的) が 613.499 です。つまり、この関数が呼び出すほかの関数が使用している CPU 時間は短いが、work_run_usrcpu() 関数自体がもっとも長い時間を消費しています。
一部の関数がボールドで一覧表示されています。これらの関数を呼び出すソースファイルに移動できます。work_run_usrcpu() 関数をダブルクリックします。
common.cファイルが開き、work_run_usrcpu() 関数がある 60 行目にカーソルが置かれます。この行の左マージンに、いくつかの数値が表示されます。
左マージンにある数値の上にカーソルを合わせます。これらの数値は、「関数あたりの CPU 時間」ウィンドウに表示される関数の包括的および排他的 CPU 時間と同じメトリックです。メトリックは小数第 1 位に丸められますが、マウスをメトリックに合わせると、丸める前の値が表示されます。work_run_usrcpu() 関数内で計算を行う for() ループなど、CPU を消費する行のメトリックは、common.c ソースファイルにも表示されます。
「関数あたりの CPU 時間」ウィンドウで、時間を入力して Enter を押すか、矢印を使用して秒をスクロールして、「時間フィルタ」の開始時間を 0:40 に変更します。グラフィックインジケータが、データフィルタリングコントロール上のハンドルを移動したときの状態に変更されます。ハンドルをドラッグすると、「関数あたりの CPU 時間」ウィンドウの「時間フィルタ」の設定が一致するように更新されます。重要なのは、表内の関数に対して表示されているデータがフィルタを反映して更新されるため、その時間内に使用された CPU 時間のみが表示されることです。
特定のメトリックに一致するデータにフィルタを適用することもできます。work_run_usrcpu() の「CPU 時間 (排他的) (CPU Time (Exclusive))」メトリックを右クリックします。この例では、「関数あたりの CPU 時間」ウィンドウで 43.07 を右クリックします。「次の条件の行のみ表示: > CPU 時間 (排他的) == 43.07」を選択します。すべての行がフィルタで除外され、排他的 CPU 時間が 43.07 と等しい行だけが表示されます。
「メモリー使用」インジケータには、プロジェクト実行時のメモリーヒープの経時変化が表示されます。これは、プログラム内で不要になったメモリーの開放に失敗した場所をポイントする、メモリーリークの特定に使用できます。メモリーリークは、プログラムのメモリー消費が増加する原因となります。メモリーリークが発生しているプログラムの実行時間が長くなると、結果的に使用できるメモリーが不足する場合があります。
「実行モニター」の時間スライダを左右に動かし、時間中にメモリーヒープが増減する様子を確認します。ProfilingDemo_1 ではスパイクが 4 回発生しています。最初の 2 回は Sequential Demo 中に発生し、3 回目は Parallel Demo 中に発生し、最後は Pthread Mutex Demo 中に発生しています。
「メモリーリーク」ボタンをクリックし、「メモリーリークの詳細」ウィンドウを表示します。メモリーリークを示している関数に関する詳細情報が表示されます。メモリーリークが発生している関数だけが、表の中に一覧表示されます。ボタンをクリックした時にプログラムが実行中の場合は、ボタンをクリックした時点で存在していたリークの場所が表示されます。時間が経過するとメモリーリークが増加する可能性があるため、「リフレッシュ」ボタンをクリックします。実行の終了時までメモリーリークが検出されなかった場合は、「メモリーリーク詳細 (Memory Leak Detail)」タブにメモリーリークが見つからなかったことが示されます。
開始時間と終了時間を変更してデータをフィルタリングしたり、「CPU 使用状況の調査」セクションと同様に「実行モニター」ウィンドウでオレンジ色の詳細スライダを使用できます。この例ではメモリーリークは発生していません。
関数をダブルクリックすると、対応するファイルが開き、関数でメモリーリークが発生している行が表示されます。メモリーリークメトリックがソースエディタの左側のマージンに表示されます。
CPU 使用率のメトリックの場合と同様に、マウスカーソルをメトリックに合わせて、詳細を表示します。
表内のメトリックを右クリックし、表内のデータにフィルタを適用します。表内のデータへのフィルタの適用は、すべてのプロファイリングツールで可能です。
「スレッド使用量」インジケータには、プログラムで使用されているスレッドの数と、スレッドがタスクを続行するためにロックを取得するまで待機する必要がある時点が示されます。このデータはマルチスレッドのアプリケーションで、コストのかかる待ち時間を回避するためにスレッドの同期を行う必要がある場合に有用です。
「スレッド使用量」インジケータに、プロジェクトの実行時に実行されたスレッドの数が示されます。時間スライダを開始時点まで戻し、Parallel Demo が開始するまでスレッドの数が 1 であることを確認します。次の図ではこれは 8:07 であり、この時点で 1 から 32 スレッドに急増しています。
表示スライダの終了ポイントハンドルを、Parallel Demo の開始位置に移動します。
同期間の「CPU 使用率」インジケータおよび「メモリー使用」インジケータでは、CPU 時間とメモリーを使用する何らかのアクティビティーを実行している 1 つのスレッドが示されています。これは、メインスレッドがファイルへの書き込みを行い、いくつかの計算を連続して行う、Sequential Demo の部分に相当します。CPU 使用率とメモリー使用は、どちらもユーザーが Enter を押すのをプログラムが待機している間に減少し、スレッド数は 1 のままになります。
タイムスライダを右にスライドさせ、スレッドが増加する 2 か所のポイントを確認します。
8:07 でのスレッドの増加は、プロジェクト実行の Parallel Demo 部分に対応しています。メインスレッドは、フィルへの書き込みと並列計算実行を処理するため、追加スレッドを開始します。メモリー使用量と CPU 使用率が増加しているが、2 つのタスクがかなり短い期間で完了しています。
Parallel Demo スレッドの終了後、スレッド数が 1 に戻り、メインスレッドはユーザーが Enter を押すのを待機します。スレッド数は、プログラムの Pthread Mutex Demo 部分の実行時にふたたび増加します。
Pthread Mutex Demo 部分でロック待機がオレンジ色で表示されています。Pthread Mutex Demo では、複数のスレッドによる特定の関数へのアクセス競合を防ぐために相互排他ロックが使用されますが、これがスレッドがロックの取得を待機する原因です。
「同期の問題」ボタンをクリックし、プロジェクトのスレッドロックに関する詳細を表示します。「スレッド同期の詳細」ウィンドウが開き、相互排他ロックを取得するために待機する必要がある関数が一覧表示されます。また、関数が待機に費やすミリ秒での秒数のメトリックと、関数がロックを待機する必要のある回数が表示されます。この例では、同期の問題は発生していません。
プログラムの実行中に「同期の問題」ボタンをクリックした場合、リフレッシュボタン
をクリックして表示を更新し、最新のスレッドロック情報にする必要がある場合があります。
「待ち時間」列をクリックし、待機時間が長い順に関数をソートします。
「ロック待機」列をクリックし、関数内でスレッドが待機した回数の順に関数をソートします。
関数をダブルクリックすると、その関数がメモリー位置をロックしているソースファイルがエディタで開きます。「待ち時間」と「ロック待機」のメトリックがソースファイルの左の列に表示されます。メトリックの上にマウスポインタを合わせると、「スレッド同期の詳細」ウィンドウの表示内容と一致する詳細が表示されます。
メトリックを右クリックして「プロファイラメトリックを表示 (Show Profiler Metrics)」を選択解除します。これでメトリックはどのプロファイルツールのソースエディタにも表示されなくなります。メトリックを再度表示するには、IDE メニューの「表示」を選択し、「プロファイラメトリックを表示」を選択します。