簡體   English   中英

是否在C中廣播MPI數據

[英]MPI data broadcast or not in C

我有兩個略有不同但得到相同結果的MPI代碼。

第一個來自開源軟件包,在這兩個軟件包之間有幾個數據交換步驟:

int main ( int argc, char **argv )
{
int i,j,nx=600,nz=300,NP, MYID;
int idum[2];
float v[420][720];

for (i=0;i<420;i++){
  for (j=0;j<720;j++){
    if(i<161) { v[i][j] = 2800.0; }
    else { v[i][j] = 5200.0; }
  }
}

MPI_Init ( &argc, &argv );
MPI_Comm_size ( MPI_COMM_WORLD, &NP );
MPI_Comm_rank ( MPI_COMM_WORLD, &MYID );

if(MYID==0){
    idum[0] = nx;
    idum[1] = nz;
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(&idum,2,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&v,420*720,MPI_FLOAT,0,MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);

nx = idum[0];
nz = idum[1];

for (i=0;i<5;i++){
  printf("id=%d,v[%d][350]=%f,\n",MYID,i*100+19,v[i*100+19][350]);
}
printf("nx=%d,nz=%d\n",nx,nz);
MPI_Finalize();
exit(0);
}

我使用具有4個核心的mpirun運行代碼。 結果是:

   id=0,v[19][350]=2800.000000,
   id=0,v[119][350]=2800.000000,
   id=0,v[219][350]=5200.000000,
   id=0,v[319][350]=5200.000000,
   id=0,v[419][350]=5200.000000,
   nx=600,nz=300
   id=1,v[19][350]=2800.000000,
   id=1,v[119][350]=2800.000000,
   id=1,v[219][350]=5200.000000,
   id=1,v[319][350]=5200.000000,
   id=1,v[419][350]=5200.000000,
   nx=600,nz=300
   id=2,v[19][350]=2800.000000,
   id=2,v[119][350]=2800.000000,
   id=2,v[219][350]=5200.000000,
   id=2,v[319][350]=5200.000000,
   id=2,v[419][350]=5200.000000,
   nx=600,nz=300
   id=3,v[19][350]=2800.000000,
   id=3,v[119][350]=2800.000000,
   id=3,v[219][350]=5200.000000,
   id=3,v[319][350]=5200.000000,
   id=3,v[419][350]=5200.000000,
   nx=600,nz=300

但是我認為數據交換部分有點“多余?”,因此我將上面的代碼簡化為:

int main ( int argc, char **argv )
{
int i,j,nx=600, nz=300, NP=0, MYID;
float v[420][720];

for (i=0;i<420;i++){
  for (j=0;j<720;j++){
    if(i<161) { v[i][j] = 2800.0; }
    else { v[i][j] = 5200.0; }
  }
}

MPI_Init ( &argc, &argv );
MPI_Comm_size ( MPI_COMM_WORLD, &NP );
MPI_Comm_rank ( MPI_COMM_WORLD, &MYID );

for (i=0;i<5;i++){
  printf("id=%d,v[%d][350]=%f,\n",MYID,i*100+19,v[i*100+19][350]);
}

printf("nx=%d,nz=%d\n",nx,nz);
MPI_Finalize();
exit(0);
}

我得到的結果與第一個代碼相同。

這兩個代碼中的哪一個是正確的? 如果兩者都正確,哪個更好? 為什么我們需要在第一個代碼中包含數據交換行,或者不必?

根據代碼,我認為您要提出的問題是:

A.最好讓每個節點都做多余的工作

B.最好讓一個節點來完成結果分發工作。

答案通常是A。

要了解原因,請考慮每個程序員都應該知道的以下延遲編號:

每個程序員都應該知道的延遲數]

請注意,CPU操作基本上不需要時間(〜1ns),並且對1KB本地內存執行相當復雜的操作需要3微秒。 另一方面,通過網絡發送1KB數據需要10微秒。 因此,通過本地操作,您的移動速度(至少)快了三倍。

但這甚至比這更好。 在並行計算中,我們將“關鍵路徑”稱為我們必須執行的最長的一系列串行操作。 在我們計算然后廣播的程序中,總時間是這兩個操作的總和。 在此示例中,這是13微秒。

通信還引入了不可預測性:消息傳輸時間可能以非線性方式取決於消息長度:

MPI數據包大小與帶寬

通信帶寬也是通信進程數量的函數:

MPI帶寬與任務數量

因此,問題是:您是否要將計算速度委托給時序屬性未知的慢速網絡? 還是您想在本地快速進行冗余計算?

而且,如果您比較網絡帶寬和內存帶寬的趨勢,避免通信的動力只會增加:

網絡與內存帶寬

這就是為什么避免通信算法成為熱門話題的原因。 這意味着不僅要避免網絡節點之間的通信,還要避免RAM和CPU緩存之間的通信,甚至還要避免CPU緩存的不同級別。 計算機各部分的速度成倍地彼此不同,因此,盡可能避免系統速度變慢越來越重要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM