2010-03-06 48 views
2

所以我試圖找出發送和接收C代碼使用MPI處理器之間的信息的通信開銷。MPI_SEND和MPI_RECV開銷

我需要在發送和接收中都傳遞一個緩衝區,但是我想要做的只是在兩個處理器之間進行通信需要多長時間。

這裏是我的全部代碼:

main(int argc, char** argv){ 

int n; 
int rank; 
int time; 
int i; 
MPI_Status status; 

MPI_Init(&argc, &argv); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

if(rank == 0){ 
    n = atoi(argv[1]); 
    printf("Size of data set = %d\n", n); 
} 

MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); 

for(i = 0; i < n; i++){ 
    if(rank == 0){ 
     MPI_Send(&n, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); 
    } 

    else{ 
     MPI_Recv(&n, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); 
    } 
} 

MPI_Barrier(MPI_COMM_WORLD); 

time = clock(); 
printf("Time: %d\n", time); 

MPI_Finalize(); 
} 

我做了一些測試,我發現,它的作品時,我拿出了我循環想要的方式。那麼導致無限循環或seg故障的for循環有什麼問題?

+1

我很驚訝,即使沒有循環的作品。你的發送和接收電話使用不同的標籤,所以接收不應該返回。你有多少個進程在運行?另外,如果你打算使用MPI,你也應該使用它的定時器調用:MPI_Wtime() – Novelocrat 2010-03-07 00:07:15

+0

我所要做的就是從節點0發送到節點1,並在節點1接收。它是一個簡單的聚會處理器之間的通信開銷。 – user287979 2010-03-07 00:22:44

+0

下面有幾個正確的答案;我只想補充一點,如果你正在尋找這些時機,一套非常方便的工具是英特爾MPI基準,http://software.intel.com/zh-cn/articles/intel- mpi-benchmarks /其中包括MPI「乒乓球」計時。 – 2012-02-14 21:30:58

回答

-1

您是否試過streams benchmark

+0

STREAM與此問題完全無關。 STREAM用於測量系統上的持續內存吞吐量。問題是關於MPI。 – powerrox 2011-07-14 16:41:33

0

我相信代碼會掛起,除非您恰好使用了兩個MPI進程。

+0

回答與問題無關。 – powerrox 2011-07-14 16:45:53

1

有兩個問題:

1)有一個在代碼中沒有檢查,以確保它獲得了「數據集的大小」。如果您在沒有有效的命令行選項的情況下啓動代碼,它將會出現段錯誤或取決於您的系統,以不可預知的方式繼續。

2)發送標籤和接收不匹配。標籤必須匹配才能成功通信。如果沒有匹配的標籤,Recv會一直等到它找到匹配的發送。併發送等待,直到找到匹配的接收。

將接收中MPI_COMM_WORLD旁邊的1更改爲0,代碼將正常運行。

1

下面是一個完整的程序,它確實你問。有幾個問題會阻止原始版本的工作:

  1. 標籤不匹配,這會導致程序停滯。
  2. 沒有檢查MPI_COMM_WORLD正好包含2 MPI進程,這也將導致失速。
  3. 如果命令行上沒有參數,則可能會發生seg故障。我爲n添加了默認值。
  4. 時間將不會產生任何有用的東西,你必須發送/ recv的公司開始運行之前調用時鐘()。

祝你好運!

#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 
#include <mpi.h> 

#define TAG_NUMBER 777  // just something 
#define DEFAULT_N 10000000 // takes ~3 seconds on my laptop 


int main(int argc, char **argv) 
{ 
    int i,n,rank,size,message=0; 
    clock_t start = clock(); 
    MPI_Status status; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    // This test assumes two processes in MPI_COMM_WORLD 
    // --------------------------------------------------------------------------- 
    if (size != 2) { 
    if (rank == 0) { // only rank 0 prints 
     printf("Please run with exactly 2 processes.\n"); 
    } 
    MPI_Finalize(); 
    return 1; 
    } 

    // Collect from the command line the number of messages to send, default to 
    // DEFAULT_N. 
    // --------------------------------------------------------------------------- 
    if (rank == 0) { 
    if (argc > 1) { 
     n = atoi(argv[1]); 
    } 
    else { 
     n = DEFAULT_N; 
    } 
    printf("Number of messages to send = %d\n", n); 
    } 

    // Make sure everyone has the same n. 
    MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); 

    // --------------------------------------------------------------------------- 
    // Here we have ranks 1 and 2 exchange n messages via MPI_Send and MPI_Recv. 
    // --------------------------------------------------------------------------- 
    for (i=0; i<n; i++) { 
    if (rank == 0) { 
     MPI_Send(&message, 1, MPI_INT, 1, TAG_NUMBER, MPI_COMM_WORLD); 
    } 
    else{ 
     MPI_Recv(&message, 1, MPI_INT, 0, TAG_NUMBER, MPI_COMM_WORLD, &status); 
    } 
    } 

    MPI_Barrier(MPI_COMM_WORLD); // not really necessary 
    printf("rank %d: time = %f seconds\n", rank, 
    (double)(clock() - start)/CLOCKS_PER_SEC); 

    MPI_Finalize(); 
    return 0; 
}