0

1つのメインアレイに特定のデータを追加することを目的としたプログラムがあります。乱数テストpassesTest(randomNumber)は毎秒数百万回実行され、非常にまれにテストに合格して、乱数がアレイの最後にプッシュされます。したがって、ほとんどの場合、計算が行われている間、アレイはそこに座っているだけです。

この手順をMPIと並列化することにしました。これは、乱数テストを実行する1000個のプロセッサが大幅に高速化されると考えたためです。また、メモリの書き込みは非常にまれであるため、MPIはこの作業に適しています。残念なことに、私のプログラムは、mpirun -np 1追加するプロセスごとに最速で、大幅に遅くなります。

whileを含むループの最後にpassesTest(randomNumber)MPI::COMM_WORLD.Allgather()配列にプッシュする必要のある新しい乱数があるかどうかを示すフラグを各プロセスから収集する必要があります。フラグのいずれかがあれば、true別のフラグを実行Allgather()して実際にこのデータを収集し、各プロセスの配列のローカルコピーにプッシュします。繰り返しにAllgather()なりますが、テストに合格することはめったにないため、この2番目の実行は非常にまれです。

したがって、私のボトルネックは、新しいデータがあるかどうかを確認するために、各MPIプロセスからすべてのフラグを収集していると推測しています。各乱数のテストは高速に実行されるため、複数のプロセスからデータを収集するオーバーヘッドのために、1秒あたり数十億のwhileループが大幅に削減されたと思います。これは良い推測ですか?私はMPIを初めて使用するため、どのようなタイムスケールが関係しているかわかりませんAllgather()

これが理由である場合、テストに合格したときに他のプロセスとのみ「対話」するにはどうすればよいですか?これが本当にやりたいことのすべてです。つまり、乱数がテストに合格した場合は、他のすべてのプロセスにメッセージを送信して、実行中の処理を停止し、その番号を配列に追加します。

4

1 に答える 1

0

まず、VooとHristoIlievのコメントを強く2番目にします。

パスをチェックするために開始するMPI_Allreduce方が明らかに高速です。転送する必要のあるデータははるかに少なくなります。ただし、Allreduceにはまだ>が必要2 * log2(n) * latencyです。1000プロセスの場合、システムによっては数百マイクロ秒程度になる場合があります。1秒あたり数百万のテストがある場合、つまり各テストに数百ナノ秒しかかからない場合、個々の通信ステップがどれほど最適に設計されていても、各テスト後の一括操作によって実際にパフォーマンスが低下することが明らかになります。

現在、依存関係について知らなければ、根本的な改善を提案することは困難です。ヒットがないと仮定して、いくつかの反復を投機的に実行し、ヒットがあることがわかった後で無効な反復を破棄することを考えることができます。

それ以上に、追加する必要のある最大の乱数を決定することをお勧めMPI_Allreduceします。MAXすべてが追加されるまでそれを繰り返します。これは明らかに、通常、追加が非常に少ない場合にのみうまく機能します。

于 2013-02-28T13:47:21.153 に答える