MPIで実行されるすべてのプロセッサで同一の配列のすべての値に対する更新を含むコードの効率を改善したいと思います。私が今使っている基本的な構造は、各プロセッサのローカル配列にデータのmemcpyチャンクを入れ、それらを操作し、Allgatherv(ローカルブロックのサイズが厳密に同じではないため「v」を使用する必要があります)です。結局のところ、これは非常に効率的ではありません、すべてのタスクで同一の配列をMPIで効率的に更新
/* counts gives the parallelization, counts[RANK] is the local memory size */
/* offsets gives the index in the global array to the local processors */
memcpy (&local_memory[0], &total_vector[0], counts[RANK] * sizeof (double));
for (i = 0; i < counts[RANK]; i++)
local_memory[i] = new_value;
MPI_Allgatherv (&local_memory[0], counts[RANK], MPI_DOUBLE, &total_vector[0], counts, offsets, MPI_DOUBLE, MPI_COMM_WORLD);
:
Cでは、これは次のようになります。実際、それは実際には遅いので、並列化に興味があるほとんどのシステム・サイズで速度が向上するわけではありません。
これは、各プロセッサのグローバルベクトルのローカルチャンクだけを更新し、正しいタスクから正しいすべてのタスクを他のすべてのタスクにブロードキャストすることです。これにより、明示的なメモリ処理が回避されますが、ブロードキャストの通信コストはかなり高くなければなりません。効果的にはすべてがすべてです。
編集:このソリューションを試してみました。ここでは、タスク数をループしてその数のブロードキャスト文を実行する必要がありました。この方法はさらに悪いことです。
誰かがより良い解決策を持っていますか?
これを正しく理解していることを確認するには:各プロセッサはベクトルの特定の部分を更新する必要があります。そして、すべてのプロセッサは、最終的に他のすべてのプロセッサからアップデートを取得する必要がありますか? (彼らは同じであると思われるので) – Mysticial
あなたはそれを持っている。 – coastal
私はそれがより良くなるか悪化するかについて答えを投稿しようとしており、あなたは自分自身で答えました。私はアイデアがありません。カスタムのMPIデータ型でハックする可能性はありますが、あまりにも慣れていません。 – Mysticial