パフォーマンス ボトルネックのデバッグ
多数の (16 台より多い) VM 上でハイ パフォーマンス コンピューティング (HPC) アプリケーションを実行している場合は、より少ない台数の VM 上で、より小さい問題の実行から始めるのが最適です。 このテストでは、HPC アプリケーションが想定どおりに実行されていることを確認します。
HPC 並列アプリケーションを実行しているからといって、より多くの VM (より多くの並列プロセス) 上で実行するほど、その総経過時間 (経過した実時間) が減少し続けるとは思わないでください。 実際には、多くの密結合された HPC アプリケーションで、他の VM 上で実行しようとすると実時間がより長くなる可能性があります。
長い実時間は、いくつかの理由で発生する可能性があります。 次に例を示します。
並列アルゴリズムを非効率的に実装する可能性があります。
問題のサイズ、すなわちモデル サイズまたは自由度数 (NDOF) が、十分な大きさではありません。 より多くの並列プロセスでアプリケーションが実行されると、各プロセスによる計算の量が小さくなりすぎます。 その結果、総経過時間の合計は、並列プロセス間の通信時間によってその多くが占められます。 通信時間の増加により、合計の実時間が増加します。
関心のある問題のサイズを実行して、HPC アプリケーションがどの程度適切にスケーリングされるかを把握することが重要です。 その後、パフォーマンスとコストの観点から、許容できる並列化効率を判断できます。
次の並列化高速化の数式により、並列プロセスをさらに追加することで並列アプリケーションのパフォーマンスがどの程度向上するかが測定されます。
$${\text{並列化高速化}} = {\dfrac{\text{実時間 (1 プロセス)}}{\text{実時間 (n 個のプロセス)}}}$$
次の並列化効率の数式により、並列アプリケーションのパフォーマンスを向上させるためにプロセスを追加すると、コンピューティング リソースがどれだけ効率的に使用されるかが示されます。
$${\text{並列化効率}} = {\dfrac{\text{並列化高速化}}{\text{N 個のプロセス}}}$$
密結合された HPC アプリケーションの並列スケーリング パフォーマンスが不明な場合は、スケーリング調査を実行します。 言い換えると、1、2、4、8、16 などの並列プロセス上でアプリケーションを実行します。 並列化高速化と並列化効率を計算し、これらの結果に基づいて、使用する並列プロセスの数を決定します。
ジョブを実行する前に、Azure Linux エージェントなどの、並列スケーリングに影響する可能性のある不要なサービスを無効にすることを検討してください。 それから、ジョブが完了したらそれらのサービスを再度有効にすることができます。 このレコメンデーションは、使用可能なすべてのコアを使用していて、多数の VM にスケーリングする場合に特に当てはまります。
Azure Linux エージェントを停止するには、次のコマンドを使用します。
sudo system stop waagent.service
パフォーマンス チェック
以下の情報は、潜在的なパフォーマンスの問題を特定するのに役立ついくつかの基本的なチェックを示しています。
各 VM で適正な数のプロセスとスレッドが実行されていることをチェックする
各仮想マシン (VM) 上で適切な数のプロセスとスレッドを使用しているかどうかを判断する簡単な方法は、uptime などのツールを使用して、各 VM 上のシステム負荷の平均を取得することです。 この数値は、各 VM の予想されるプロセス数とスレッド数の合計と、ほぼ同じである必要があります。 記録された負荷の平均が、プロセスとスレッドの想定される合計数よりも低いまたは高い場合は、修正する必要のある問題を示しています。
メッセージ パッシング インターフェイス (MPI) の引数と、並列スレッド数を指定する方法を慎重に確認する必要があります。 たとえば、アプリケーションのコマンドライン引数、または OMP_NUM_THREADS
などの環境変数の値をチェックします。
プロセスとスレッドがすべての NUMA ノード ドメイン間で均等に分散されていることをチェックする
top または htop ツールを使用している場合は、コマンド ライン パラメーターとして 2
を指定することで、不均一メモリ アクセス (NUMA) ノード ドメイン ビューを選択できます。 (例: HB120_v2 の場合、このビューを使用すると 30 個の NUMA ノード ドメインが表示されます。)
ユーザー使用率の割合は、すべての NUMA ドメイン間で均等に分散されている必要があります。 そうでない場合は、MPI コマンド ライン引数と環境変数をチェックします。
次の図は、NUMA ビューでの Linux top ツールの出力を示しています。 このケースでは、各 NUMA が 50% 使用されています。
プロセスとスレッドの実行状態をチェックする
プロセスとスレッドの実行状態をチェックするには、top を使用する必要があります。 理想的には、すべてのプロセスとスレッドが実行中 (R) 状態であるべきです。
プロセスとスレッドの一部またはすべてが無停電スリープ (D) またはスリープ (S) 状態にある場合は、状況を調査してその理由を把握します。 アプリケーションのアルゴリズムの設計方法によっては、プロセスとスレッドがスリープ状態になることが通常の予期される動作である可能性があります。 ただし、リソース制約を示している可能性があります。たとえば、使用しているストレージ ソリューションによって不十分な I/O パフォーマンスが発生している場合などです。
次の数式は、並列アプリケーションがいくつかのシステム リソース (I/O など) を待機している場合に、そのアプリケーションがどの程度効率的に実行されているかを示しています。
$${\text{アプリケーション待機時間}} = {\text{実時間}} - \left( {\dfrac{\text{すべての並列プロセスの合計 CPU 時間}}{\text{並列プロセス数}}} \right)$$
アプリケーションが I/O バインドであるかどうかをチェックする
無停電スリープ (D) またはスリープ (S) 状態でかなりの時間を消費しているプロセスとスレッドは、調査が必要な I/O ボトルネックが存在することを示している可能性があります。 一部の HPC アプリケーションでは、出力の一部としてパフォーマンス プロファイルが提供されます。 これらのプロファイルには、I/O の実行に費やされた時間の割合や読み取りと書き込みの I/O レートが示されます。これも I/O ボトルネックを指し示している可能性があります。
I/O がどこで行われているかわからない場合は、iostat などのツールを使用すると役立ちます。 I/O の問題があるかどうかを確認するには、ストレージ ソリューションを、これまで使用していたものよりも速いことがわかっているものに変更します。 その後、HPC アプリケーションを再実行します。 たとえば、高速のローカル NVMe SSD または RAM ディスクを使用できます。
この変更を行った後、次の質問を自問してください。I/O 時間は改善されましたか? 全体的な実時間は向上していますか。 問題がない場合には、どの程度までなら耐えられるか。
アプリケーションがネットワークにバインドされているかどうかをチェックする
アプリケーションで、プロセス通信 (一般に MPI 通信) を実行するために費やされる全体の実時間の割合を判断します。
アプリケーションがネットワークにバインドされている場合は、HPC アプリケーションの実行時に InfiniBand ネットワークを使用していることを確認します。 ハイブリッド並列バージョンが使用可能な場合は、それによってネットワーク通信時間が短縮されるかどうかを判断します。
ソース コードにアクセスできる場合は、通信を実装するためのより効率的な方法があるかどうかを確認します。 たとえば、ポイントツーポイントではなく集合演算を使うか、同期通信ではなく非同期通信の使用を試します。