10

一連のスレーブプロセスにコマンドを渡す1つのマスタープロセスで構成されるMPIプログラムがあります。コマンドを受信すると、スレーブはsystem()を呼び出してそれを実行します。スレーブがコマンドを待機している間、スレーブはそれぞれのCPUを100%消費しています。Probe()はタイトなループにあるように見えますが、それは推測にすぎません。これを引き起こしている可能性があると思いますか、それを修正するために何ができますか?

コマンドを待機するスレーブプロセスのコードは次のとおりです。logとtopコマンドを同時に見ると、スレーブがCPUを消費しているとき、それらはこの関数内にあることがわかります。

MpiMessage
Mpi::BlockingRecv() {
  LOG(8, "BlockingRecv");

  MpiMessage result;
  MPI::Status status;

  MPI::COMM_WORLD.Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, status);
  result.source = status.Get_source();
  result.tag = status.Get_tag();

  int num_elems = status.Get_count(MPI_CHAR);
  char buf[num_elems + 1];
  MPI::COMM_WORLD.Recv(
     buf, num_elems, MPI_CHAR, result.source, result.tag
  );
  result.data = buf;
  LOG(7, "BlockingRecv about to return (%d, %d)", result.source, result.tag);
  return result;
}
4

2 に答える 2

14

はい; ほとんどのMPI実装は、パフォーマンスのために、ビジーウェイト操作をブロックするのを待ちます。プロセッサで気になるのはMPIジョブだけであり、通信の待機中にタスクがブロックされた場合は、その通信を継続的にポーリングして遅延を減らすことが最善の方法です。そのため、メッセージが到着してからMPIタスクに渡されるまでの間に実質的に遅延はありません。これは通常、「実際の」処理が行われていない場合でも、CPUが100%に固定されていることを意味します。

これは、ほとんどのMPIユーザーにとっておそらく最良のデフォルトの動作ですが、必ずしも希望どおりであるとは限りません。通常、MPI実装では、これをオフにすることができます。OpenMPIでは、MCAパラメータを使用してこの動作をオフにすることができます。

mpirun -np N --mca mpi_yield_when_idle 1 ./a.out
于 2013-01-28T13:14:11.203 に答える
4

MPIメッセージを待つ方法は3つあるようです。

  1. 積極的なビジーウェイト。これにより、メッセージが受信コードにできるだけ早く届きます。一部のプロセッサは、着信メッセージをチェックするだけです。すべてのプロセッサをこの状態にすると、システムの残りの部分が非常に遅くなります。MPIはデフォルトでアグレッシブモードを使用します。
  2. 劣化したビジーウェイト。これは、ビジー待機を実行している間、他のプロセスに譲ります。要求するプロセスの数がプロセッサの数よりも多い場合、MPIは劣化モードに切り替わります。MCAパラメータを使用して、アグレッシブモードまたはデグレードモードを強制することもできます。
  3. ポーリング。低下したビジー待機でもビジー待機であり、待機しているプロセスごとに1つのプロセッサが100%に固定されたままになります。システム上に競合したくない他のタスクがある場合は、ブロッキング受信を呼び出す前に、スリープ呼び出しを使用してループで呼び出すことができます。MPI_Iprobe()100ミリ秒のスリープは私のタスクに対して十分に応答性があり、ワーカーがアイドル状態のときでもCPU使用率を最小限に抑えます。

いくつか検索したところ、プロセッサを他のタスクと共有していない場合は、ビジーウェイトが必要であることがわかりました。

于 2015-01-28T00:43:56.567 に答える