我想使用 OpenMPI 和 C 在計算集群中運行數值模擬。但是,每個處理器都有一個A恒定且相等的大矩陣。為了避免分配過多不必要的記憶體,我想將具有共享記憶體的處理器(即它們在同一個計算節點中)分組,并且每個節點 malloc 中只有一個處理器并設定那個大矩陣A。然后節點中的所有其他處理器應該能夠讀取該矩陣。
另一個問題正是我需要的,但它在 Fortran 中。我接受了它的答案并用 C 制作了一個原型,但它沒有按預期作業。由于我無法理解的原因,回傳的記憶體地址MPI_Win_allocate_shared偏移了1個位移單位。請參見下面的代碼:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int
main ()
{
MPI_Init(NULL, NULL);
int num_processors;
MPI_Comm_size(MPI_COMM_WORLD, &num_processors);
int proc_global_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &proc_global_rank);
// Split de global communicator, grouping by shared memory
MPI_Comm compute_comm;
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &compute_comm);
int proc_compute_rank;
MPI_Comm_rank(compute_comm, &proc_compute_rank);
// Create the window
const int ARRAY_SIZE = 1;
int* shared_data;
MPI_Aint shared_data_size;
if (proc_compute_rank == 0) {
shared_data_size = ARRAY_SIZE * sizeof(int);
} else {
shared_data_size = 0;
}
int disp_unit = sizeof(int);
MPI_Win window;
MPI_Win_allocate_shared(shared_data_size, disp_unit, MPI_INFO_NULL, compute_comm, &shared_data, &window);
if (proc_compute_rank == 0) {
shared_data[0] = -10;
}
// get the location of the shared memory segment
if (proc_compute_rank != 0) {
MPI_Win_shared_query(window, 0, &shared_data_size, &disp_unit, shared_data);
}
MPI_Win_fence(0, window); // wait for shared variables to be ready to be used
MPI_Barrier(compute_comm);
printf("rank %d, value[0] = %d\n", proc_compute_rank, shared_data[0]); // prints a wrong value
printf("rank %d, value[-1] = %d\n", proc_compute_rank, shared_data[-1]); // prints correct value
// do calculations...
MPI_Win_fence(0, window); // wait for shared variables to be no longer needed
MPI_Barrier(compute_comm);
MPI_Win_free(&window);
MPI_Finalize();
return EXIT_SUCCESS;
}
uj5u.com熱心網友回復:
代碼中的真正問題是您傳遞了一個int*to MPI_Win_query,但是該呼叫需要設定指標,因此您需要傳遞一個int**, 在您的情況下意味著&shared_data。
可能存在第二個問題:通過顯式設定視窗緩沖區的內容,您正在假設“統一記憶體模型”,這很可能是這種情況。如有疑問,請測驗
MPI_Win_get_attr(the_window,MPI_WIN_MODEL,&modelstar,&flag);
并確保該引數不是MPI_WIN_SEPARATE,在這種情況下,您必須MPI_Put將資料放入視窗。
順便說一句,您對獲得不同地址的行程進行了觀察。即使您修復了與號錯誤,這也將保持真實!程式員所認為的地址只是一個邏輯地址,它被“頁表”翻譯成物理地址。但是每個行程都有自己的頁表,因此相同的物理地址將在行程中轉換為不同的邏輯地址,因此,是的,即使您有正確的指標,您也會得到不同的列印十六進制地址。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/467415.html
上一篇:C是否有[[nodiscard]]機制在忽略值時發出警告?
下一篇:makefile不改變輸入檔案名
