並列コードのプロファイル
並列プロファイラーでは、特に並列プールのワーカー用に profile
コマンドとプロファイル ビューアーが拡張され、各ワーカーが各関数の評価に費やす時間、および他のワーカーとの通信または通信待ちに費やす時間を表示できます。標準プロファイルおよびその表示の詳細については、パフォーマンス向上のためのコードのプロファイリングを参照してください。
並列プロファイリングでは、profile
と同様の使用方法で mpiprofile
コマンドを使用します。
並列コードのプロファイル
この例では、並列プール内のワーカーで並列プロファイラーを使用して並列コードをプロファイルする方法を説明します。
並列プールを作成します。
numberOfWorkers = 3; pool = parpool(numberOfWorkers);
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 3).
mpiprofile
を有効にして、並列プロファイル データを収集します。
mpiprofile on
並列コードを実行します。この例の目的上、一連の値に対して反復するシンプルな parfor
ループを使用します。
values = [5 12 13 1 12 5]; tic; parfor idx = 1:numel(values) u = rand(values(idx)*3e4,1); out(idx) = max(conv(u,u)); end toc
Elapsed time is 51.886814 seconds.
コードの終了後、mpiprofile viewer
を呼び出して並列プロファイラーから結果を表示します。このアクションは、プロファイル データの収集停止も行います。
mpiprofile viewer
レポートには、ワーカーで実行される各関数の実行時間に関する情報が表示されます。各ワーカーで最も長い時間を要する関数を調べることができます。
通常、合計実行時間が最長と最短のワーカーを比較すると便利です。これを行うには、レポートの [最長と最短合計時間] をクリックします。この例では、あるワーカーで conv
が複数回実行され、他のワーカーより大幅に長い時間を要したことが観察されます。この観察は、作業負荷がワーカー間に均等に分散されていなかった可能性を示唆しています。
各反復の作業負荷が不明の場合は、次のサンプル コードのように反復をランダム化することを推奨します。
values = values(randperm(numel(values)));
parfor
ループ内の各反復の作業負荷が既知の場合は、parforOptions
を使用して、ワーカーのサブレンジへの反復の分割を制御します。詳細については、parforOptions
を参照してください。
この例では、values(idx)
が大きくなるほど、反復の計算量が多くなります。values
内の値の連続するペアにはそれぞれ、最大および最小の計算量が表示されています。作業負荷がより良く分散されるように、parfor
の反復をサイズ 2
のサブレンジに分割する parfor
のオプション セットを作成します。
opts = parforOptions(pool,"RangePartitionMethod","fixed","SubrangeSize",2);
並列プロファイラーを有効にします。
mpiprofile on
前と同じコードを実行します。parfor
のオプションを使用するには、parfor
の 2 番目の入力引数に渡します。
values = [5 12 13 1 12 5]; tic; parfor (idx = 1:numel(values),opts) u = rand(values(idx)*3e4,1); out(idx) = max(conv(u,u)); end toc
Elapsed time is 33.813523 seconds.
並列プロファイラーの結果を可視化します。
mpiprofile viewer
このレポートの [最長と最短合計時間] を選択して、合計実行時間が最短と最長のワーカーを比較します。今回はすべてのワーカーで、conv
の複数回の実行に同様な時間がかかっています。今回の作業負荷はより良く分散されています。
並列プロファイル データの解析
プロファイラーは、各ワーカーでのコード実行とワーカー間の通信に関する情報を収集します。こうした情報には以下の項目が含まれます。
各ワーカーでの各関数の実行時間。
各関数での各コード行の実行時間。
各ワーカー間で転送されるデータ量。
各ワーカーの通信待ち時間。
この節の残りの部分では、並列プロファイル ビューアーのいくつかの機能について例示します。この例では、クラスター ワーカーの並列プールで並列実行される分散配列の行列乗算をプロファイルします。
parpool
Starting parallel pool (parpool) using the 'MyCluster' profile ... Connected to the parallel pool (number of workers: 64).
R1 = rand(5e4,'distributed'); R2 = rand(5e4,'distributed'); mpiprofile on R = R1*R2; mpiprofile viewer
最後のコマンドにより [プロファイラー] ウィンドウが開き、まずワーカー 1 の並列プロファイル概要 (つまり、関数の概要レポート) が表示されます。
関数の概要レポートでは、以下のヘッダーをもつ並べ替え可能な列に、ワーカーで実行された各関数のデータが表示されます。
列ヘッダー | 説明 |
---|---|
Calls | このワーカーで関数が呼び出された回数 |
Total Time | このワーカーがこの関数の実行に費やした合計時間 |
Self Time | 子関数やローカル関数内でなく、この関数内でこのワーカーが費やした時間 |
Total Comm Time | このワーカーが他のワーカーとの間のデータ転送に費やした合計時間 (データの受信待ち時間も含む) |
Self Comm Waiting Time | このワーカーがこの関数の実行中に他のワーカーからのデータの受信待機に費やした時間 |
ワーカー間データの合計 | この関数についてこのワーカーが送受信したデータ量 |
Computation Time Ratio | この関数の計算に費やされた時間の、この関数の合計時間 (通信時間も含む) に対する割合 |
Total Time Plot | このワーカーでのこの関数の Self Time、Self Comm Waiting Time および Total Time の相対サイズを示す棒グラフ |
関数の実行の詳細については、リストからその関数の名前を選択してください。codistributor1d.hMtimesImpl
の関数詳細レポートには次のリストが記載されます。
レポートに表示されるコードは、クライアントから取得されます。ワーカーで通信ジョブが実行された後にクライアントでコードが変更された場合、またはワーカーが異なるバージョンの関数を実行している場合、実際に実行された内容が正確には表示に反映されていない可能性があります。
各ワーカーの情報を表示することも、比較コントロールを使用して複数のワーカーの情報を同時に表示することもできます。[自動で比較対象を選択] には 2 つのボタンがあり、コードの実行に最長時間と最短時間を要したワーカーのデータ、またはワーカー間の通信に最長時間と最短時間を費やしたワーカーのデータを比較できます。[手動で比較対象を選択] では、特定のワーカーまたは特定の条件を満たすワーカーのデータを比較することができます。
次の概要レポートのリストには、[自動で比較対象を選択] の [比較 (合計時間の最長と最短)] を使用した結果が表示されています。比較結果には、コードの実行時間が最長のワーカー 50 と最短のワーカー 62 のデータが比較表示されています。
次の図には、プロファイル収集時間中に実行されたすべての関数の概要が表示されています。[手動で比較対象を選択] の [最長時間の集計] では、すべての関数について全ワーカーのデータを検討して、各関数に費やした時間が最長であるワーカーを判定します。各関数名の右側には、その関数の実行に最も長い時間を要したワーカーが表示されています。他の列には、そのワーカーのデータが記載されています。
次の図は、各関数の実行に費やした時間が最長だったワーカーと最短だったワーカーに関する概要レポートを示したものです。この概要は、[手動で比較対象を選択] の [最長時間の集計] と [0 より大きい最短時間の集計] によって生成されています。いずれの集計設定も、最長と最短の値を求めて、プロファイラーがすべての関数についてすべてのワーカーのデータを検討するよう指定しています。このレポートには、ワーカー 50 とワーカー 62 の codistributor1d.hMtimesImpl
に関するデータがリストされています。これらのワーカーで、この関数に費やした時間が最長および最短であるためです。同様に、他の関数もリストされています。
詳細な比較を表示するには、比較の概要リストで関数名を選択します。codistributor1d.hMtimesImpl
の詳細な比較では、次のように両方のワーカーのデータが行ごとに表示されます。
通信データのプロットを表示するには、[Figure を表示] メニューの [ワーカー間通信ごとのすべてをプロット] を選択します。プロット ビュー レポートの上部には、各ワーカーがすべての関数について他のワーカーそれぞれから受信したデータ量がプロットされます。
ワーカー間の通信時間のプロットのみを表示するには、[Figure を表示] メニューの [ワーカーごとの通信時間をプロット] を選択します。
前の 2 つの図にあるようなプロットは、たとえば対話型分散配列の分割スキームを変更することにより、負荷をワーカー間にバランスよく分散する最良の方法を決める助けとなります。