MPIのスレッドセーフはそのままでは機能しません。まず、実装が実際に一度にMPI呼び出しを行う複数のスレッドをサポートしていることを確認する必要があります。Open MPIなどの一部のMPI実装では、ビルド時にライブラリを特別なオプションで構成する必要があります。次に、適切なスレッドサポートレベルで初期化するようにMPIに指示する必要があります。現在、MPI標準では、次の4つのレベルのスレッドサポートが定義されています。
MPI_THREAD_SINGLE
-ユーザーコードがシングルスレッドであることを意味します。これは、使用されている場合にMPIが初期化されるデフォルトのレベルですMPI_Init()
。
MPI_THREAD_FUNNELED
-ユーザーコードがマルチスレッドであるが、メインスレッドのみがMPI呼び出しを行うことを意味します。メインスレッドは、MPIライブラリを初期化するスレッドです。
MPI_THREAD_SERIALIZED
-ユーザーコードはマルチスレッドですが、MPIライブラリへの呼び出しはシリアル化されていることを意味します。
MPI_THREAD_MULTIPLE
-ユーザーコードがマルチスレッドであり、すべてのスレッドが同期なしでいつでもMPI呼び出しを行うことができることを意味します。
スレッドサポートを使用してMPIを初期化するには、次MPI_Init_thread()
の代わりにを使用する必要がありMPI_Init()
ます。
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
if (provided < MPI_THREAD_MULTIPLE)
{
printf("ERROR: The MPI library does not have full thread support\n");
MPI_Abort(MPI_COMM_WORLD, 1);
}
廃止された(そしてMPI-3から削除された)C ++バインディングを持つ同等のコード:
int provided = MPI::Init_thread(argc, argv, MPI::THREAD_MULTIPLE);
if (provided < MPI::THREAD_MULTIPLE)
{
printf("ERROR: The MPI library does not have full thread support\n");
MPI::COMM_WORLD.Abort(1);
}
スレッドサポートレベルは次のように順序付けられます:MPI_THREAD_SINGLE
<<< MPI_THREAD_FUNNELED
、したがって、他の提供されたレベルは、数値が低くなります-そのため、上記のMPI_THREAD_SERIALIZED
コードはそのように記述されています。MPI_THREAD_MULTIPLE
MPI_THREAD_MULTIPLE
if (...)
MPI_Init(&argc, &argv)
と同等MPI_Init_thread(&argc, &argv, MPI_THREAD_SINGLE, &provided)
です。実装は、要求されたレベルで正確に初期化する必要はありません。むしろ、provided
出力引数で返される他のレベル(より高いまたはより低い)で初期化することができます。
詳細については、MPI標準の§12.4を参照してください。ここから無料で入手できます。
ほとんどのMPI実装では、レベルでのスレッドサポートMPI_THREAD_SINGLE
は、実際にはレベルで提供されるものと同等です。これは、実際MPI_THREAD_SERIALIZED
にあなたが観察したものとまったく同じです。
使用するMPI実装を指定していないので、ここに便利なリストがあります。
をサポートするには、OpenMPIを適切なフラグを有効にしてコンパイルする必要があることはすでに述べましたMPI_THREAD_MULTIPLE
。ただし、別の問題があります。そのInfiniBandコンポーネントはスレッドセーフではないため、Open MPIは、フルスレッドサポートレベルで初期化された場合、ネイティブのInfiniBand通信を使用しません。
Intel MPIには、完全なマルチスレッドをサポートするものとサポートしないものの2つの異なる種類があります。マルチスレッドサポートは-mt_mpi
、MTバージョンとのリンクを有効にするオプションをMPIコンパイララッパーに渡すことで有効になります。このオプションは、OpenMPサポートまたは自動並列化機能が有効になっている場合にも暗示されます。フルスレッドサポートが有効になっている場合、IMPIのInfiniBandドライバーがどのように機能するかわかりません。
MPICH(2)はInfiniBandをサポートしていないため、スレッドセーフであり、おそらく最新バージョンはそのままでMPI_THREAD_MULTIPLE
サポートを提供します。
MVAPICHは、Intel MPIが構築される基盤であり、InfiniBandをサポートします。InfiniBandを搭載したマシンで使用した場合、フルスレッドサポートレベルでどのように動作するかわかりません。
最近の多くのコンピューティングクラスターはInfiniBandファブリックを使用しているため、マルチスレッドのInfiniBandサポートに関する注意事項は重要です。IBコンポーネント(openib
Open MPIのBTL)を無効にすると、ほとんどのMPI実装は、TCP / IP(Open MPIのBTL)などの別のプロトコルに切り替わりますtcp
。これにより、通信がはるかに遅くなり、潜在的になります。