2

所以我试图找出在 C 代码中使用 MPI 在处理器之间发送和接收信息的通信开销。

我需要在发送和接收中传递一个缓冲区,但我想做的只是计算在两个处理器之间进行 n 通信所需的时间。

这是我的整个代码:

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 循环有什么问题?

4

4 回答 4

1

下面是一个完整的程序,可以满足您的要求。有几个问题会阻止原始版本工作:

  1. 标签不匹配,这将导致程序停止。
  2. 没有检查 MPI_COMM_WORLD 是否正好包含 2 个 MPI 进程,这也会导致停顿。
  3. 如果命令行上没有参数,您可能会遇到段错误。我为 . 添加了一个默认值n
  4. 计时不会产生任何有用的东西,您必须在发送/接收开始运行之前调用时钟()。

祝你好运!

#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;
}
于 2012-02-13T21:59:55.667 回答
1

有两个问题:

1)代码中没有检查以确保它收到“数据集的大小”。如果您在没有有效命令行选项的情况下启动代码,它将出现段错误或根据您的系统,以不可预知的方式继续。

2)发送和接收中的标签不匹配。标签必须匹配才能成功通信。如果没有匹配的标签,Recv 将永远等待,直到找到匹配的发送。并发送等待,直到找到匹配的接收。

将接收中 MPI_COMM_WORLD 旁边的 1 更改为 0,代码将正常运行。

于 2011-07-14T16:55:00.430 回答
0

我相信除非您恰好使用两个 MPI 进程,否则代码会挂起。

于 2010-03-09T06:58:29.600 回答
-1

您是否尝试过流基准测试

于 2010-03-07T01:38:01.160 回答