我是MPI的新手。我有4個進程:進程1到3填充一個向量並將其發送到進程0,進程0將向量收集到一個很長的向量中。我的代碼可以工作(發佈時間太長),但進程0的recv操作笨拙而且非常緩慢。MPI按根進程收集數組
在抽象中,代碼執行以下操作:
MPI::Init();
int id = MPI::COMM_WORLD.Get_rank();
if(id>0) {
double* my_array = new double[n*m]; //n,m are int
Populate(my_array, id);
MPI::COMM_WORLD.Send(my_array,n*m,MPI::DOUBLE,0,50);
}
if(id==0) {
double* all_arrays = new double[3*n*m];
/* Slow Code Starts Here */
double startcomm = MPI::Wtime();
for (int i=1; i<=3; i++) {
MPI::COMM_WORLD.Recv(&all_arrays[(i-1)*m*n],n*m,MPI::DOUBLE,i,50);
}
double endcomm = MPI::Wtime();
//Process 0 has more operations...
}
MPI::Finalize();
事實證明,endcomm - startcomm
佔的總時間的50%(0.7秒相比1.5秒的程序來完成)。
有沒有更好的方式從進程1-3接收向量並將它們存儲在進程0的all_arrays
?
我檢出了MPI :: Comm :: Gather,但我不確定如何使用它。特別是,它是否允許我指定進程1的數組是all_arrays中的第一個數組,第二個進程2的數組等等?謝謝。
編輯:我刪除了「慢」的循環,而是放之間以下的「如果」塊:
MPI_Gather(my_array,n*m,MPI_DOUBLE,
&all_arrays[(id-1)*m*n],n*m,MPI_DOUBLE,0,MPI_COMM_WORLD);
同樣的性能下降造成的。這是否與這樣一個事實有關:在嘗試下一個個體之前,根過程「等待」每個個體接收完成?或者,這不是正確的思考方式嗎?
只是一個簡單的評論 - C++綁定在當前的MPI標準版本2.2中被棄用,並且在即將到來的MPI 3.0中將被完全刪除。爲了便於攜帶,建議您學習並使用C接口。 –
程序中有多少'n'和'm',以及您的機器之間有什麼樣的連接? – suszterpatt
Hristo,謝謝 - 我將我的代碼更改爲C接口。 – covstat