簡體   English   中英

MPI_Send和MPI_Recv開銷

[英]MPI_Send and MPI_Recv overhead

因此,我試圖找出使用C代碼中的MPI在處理器之間發送和接收信息的通信開銷。

我需要在發送和接收中都傳遞一個緩沖區,但是我要做的只是計時兩個處理器之間進行通信所花費的時間。

這是我的整個代碼:

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();
}

我做了一些測試,發現當我取出for循環時,它可以按照我想要的方式工作。 那么,導致無限循環或段錯誤的for循環又有什么問題呢?

有兩個問題:

1)在代碼中沒有檢查以確保它收到了“數據集的大小”。 如果您在沒有有效命令行選項的情況下啟動代碼,它將導致段錯誤或取決於您的系統,以無法預測的方式繼續進行。

2)發送和接收中的標簽不匹配。 標簽必須匹配才能成功通信。 沒有匹配的標簽,Recv將永遠等待直到找到匹配的發送。 發送等待直到找到匹配的接收方。

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

下面是一個完整的程序,它可以滿足您的要求。 存在一些會阻止原始版本工作的問題:

  1. 標簽不匹配,這將導致程序停止。
  2. 沒有檢查MPI_COMM_WORLD是否恰好包含2個MPI進程,這也會導致停頓。
  3. 如果命令行上沒有參數,則可能會出現段錯誤。 我為n添加了默認值。
  4. 計時不會產生任何有用的信息,您必須在發送/接收開始運行之前調用clock()。

祝好運!

#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;
}

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

您是否嘗試過流基准測試

暫無
暫無

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

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