您可以選擇根級別,並將異步發送與源自此根目錄的異步廣播組合在一起。下面是一個小例子:
#include <stdio.h>
#include <mpi.h>
int main()
{
int size, rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
const int root = 0;
const int found_tag = 42;
const long long chunk = 100000ll;
const long long target = 134861523ll;
MPI_Request found_request;
long long found_item;
if (rank == root) {
MPI_Irecv(&found_item, 1, MPI_LONG_LONG, MPI_ANY_SOURCE, found_tag, MPI_COMM_WORLD, &found_request);
} else {
MPI_Ibcast(&found_item, 1, MPI_LONG_LONG, root, MPI_COMM_WORLD, &found_request);
}
for (long long my_number = rank;; my_number += size) {
if (my_number == target) {
found_item = my_number;
printf("I found it: %d, %lld\n", rank, found_item);
// We don't stop here, we will continue until the root tells us to stop
// This also works if we are the root
MPI_Send(&my_number, 1, MPI_LONG_LONG, root, found_tag, MPI_COMM_WORLD);
}
// Avoid checking MPI_Test too often.
if ((1 + (my_number/size)) % chunk == 0) {
if (rank == root) {
int found = 0;
MPI_Test(&found_request, &found, MPI_STATUS_IGNORE);
if (found) {
printf("Someone told me that he found it: %d, %lld\n", rank, found_item);
MPI_Request bcast_request;
MPI_Ibcast(&found_item, 1, MPI_LONG_LONG, root, MPI_COMM_WORLD, &bcast_request);
MPI_Wait(&bcast_request, MPI_STATUS_IGNORE);
break;
}
} else {
int found = 0;
MPI_Test(&found_request, &found, MPI_STATUS_IGNORE);
if (found) {
break;
}
}
}
}
printf("%d, %lld\n", rank, found_item);
MPI_Finalize();
}
此代碼假定您只能找到一個確切的數字 - 一次。查找多個號碼將需要一些額外的代碼。
正如你所說,你不能發佈廣播與未知的發件人。現在你可以發佈一個MPI_Allreduce
(或者甚至MPI_Allgather
) - 之後所有的隊伍都會知道發現的價值。但是,您不能只發布一次異步版本 - 因爲在發佈後您無法更改該值。
謝謝 - 你的答案可能會起作用,但是,我得到的任務不需要一個處理通信的通信器(在你的情況下是根級)。 我的程序會找到多個不同等級的解決方案(不僅是數字,而是數組),需要分佈多次。 有沒有辦法繞過通過一個處理器通信? – Markus
@Markus,沒有涉及我能想到的一箇中心元素的所有選項將效率較低。要麼以某種方式重新實施集體活動,要麼定期發佈集體活動,而不是完全異步活動(如我最後一段所述)。沒有根級別似乎是一個任意的限制,因爲它在這種情況下顯然不會限制可伸縮性。處理多個找到的號碼是一個相當直接的擴展,只是重新發布請求。給出更具體的例子需要更具體的問題描述。 – Zulan
好的,我明白你來自哪裏。我現在會使用你的建議,因爲它很快實施並且應該工作。但是,瞭解我的顧問後,我可能不得不手動實現一些類似於廣播的二項式通信樹。一旦我做了一些基準測試並收到一些反饋,我會回來。 – Markus