Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C MPI_发送和MPI_接收开销_C_Mpi - Fatal编程技术网

C MPI_发送和MPI_接收开销

C MPI_发送和MPI_接收开销,c,mpi,C,Mpi,因此,我试图找出使用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, &ran

因此,我试图找出使用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();
}
main(int-argc,char**argv){
int n;
整数秩;
整数时间;
int i;
MPI_状态;
MPI_Init(&argc,&argv);
MPI通信等级(MPI通信世界和等级);
如果(秩==0){
n=atoi(argv[1]);
printf(“数据集的大小=%d\n”,n);
}
MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
对于(i=0;i

我做了一些测试,我发现当我取出for循环时,它按照我希望的方式工作。那么,导致无限循环或seg故障的for循环有什么问题呢?

您是否尝试过该方法?

我认为除非您使用两个MPI进程,否则代码将挂起。

有两个问题:

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

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


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

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

  • 标记不匹配,这将导致程序暂停
  • 没有检查MPI_COMM_WORLD是否正好包含2个MPI进程,这也会导致暂停
  • 如果命令行中没有参数,则可能会出现seg错误。我为
    n
    添加了一个默认值
  • 计时不会产生任何有用的结果,您必须在发送/接收开始运行之前调用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;
    }
    
    #包括
    #包括
    #包括
    #包括
    #定义标签号777//
    #定义默认值\u N 10000000//在我的笔记本电脑上大约需要3秒钟
    int main(int argc,字符**argv)
    {
    int i,n,秩,大小,消息=0;
    时钟启动=时钟();
    MPI_状态;
    MPI_Init(&argc,&argv);
    MPI通信等级(MPI通信世界和等级);
    MPI_通信大小(MPI_通信世界和大小);
    //本测试假设MPI_COMM_世界中有两个进程
    // ---------------------------------------------------------------------------
    如果(尺寸!=2){
    如果(秩==0){//只打印秩0
    printf(“请正好运行两个进程。\n”);
    }
    MPI_Finalize();
    返回1;
    }
    //从命令行收集要发送的消息数,默认为
    //默认值。
    // ---------------------------------------------------------------------------
    如果(秩==0){
    如果(argc>1){
    n=atoi(argv[1]);
    }
    否则{
    n=默认值\u n;
    }
    printf(“要发送的邮件数=%d\n”,n);
    }
    //确保每个人都有相同的n。
    MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
    // ---------------------------------------------------------------------------
    //在这里,排名1和排名2的用户通过MPI_发送和MPI_接收交换n条消息。
    // ---------------------------------------------------------------------------
    
    对于(i=0;我很惊讶,即使没有循环也可以工作。您的发送和接收调用使用不同的标记,因此接收永远不会返回。您正在运行多少进程?此外,如果要使用MPI,也应该使用它的计时器调用:MPI\u Wtime()我所要做的只是从节点0发送到节点1,然后在节点1接收。这是处理器之间通信开销的一个简单集合。下面有几个正确答案;我只想补充一点,如果您正在寻找此类计时,一组非常方便的工具是Intel MPI基准测试,其中包括MPI“乒乓”计时。流与此问题完全无关。流用于测量系统上的持续内存吞吐量。此问题与MPI有关。答案与此问题无关。