2013-03-18 69 views
4

所以我有一个双打数组。我希望每5分钟发送一次,以便接收进程。所以基本上,我需要一种发送特定双打的方式,在它们之间迈进。除了将双打存储到发送缓冲区之外,是否有这样的功能?制作我自己的派生类型会更好吗?MPI - 发送数组的片段

回答

7

您应该创建一个MPI数据类型;它给人的MPI库的机会,以避免额外的副本从数组编组,这是非常简单的使用做,在这种情况下,MPI_Type_vector()

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

int main(int argc, char** argv) 
{ 
    int size, rank; 
    const int bigsize=50; 
    const int stride = 5; 
    const int count = (bigsize + stride - 1)/stride; 

    const int sender = 0; 
    const int receiver = 1; 
    const int mytag = 1; 

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

    if (size < 2) { 
     fprintf(stderr,"%s: Require at least two processors.\n", argv[0]); 
     MPI_Finalize(); 
     exit(-1); 
    } 


    if(rank == sender) 
    { 
     double bigarray[bigsize]; 
     for (int i=0; i<bigsize; i++) 
      bigarray[i] = 0.; 

     for (int i=0; i<bigsize; i+=stride) 
      bigarray[i] = i/stride; 

     printf("[%d]: ", rank); 
     for (int i=0; i<bigsize; i++) 
      printf("%lf ", bigarray[i]); 
     printf("\n"); 

     MPI_Datatype everyfifth; 

     MPI_Type_vector(count, 1, stride, MPI_DOUBLE, &everyfifth); 
     MPI_Type_commit(&everyfifth); 

     MPI_Send(bigarray, 1, everyfifth, receiver, mytag, MPI_COMM_WORLD); 

     MPI_Type_free(&everyfifth); 
    } 
    else if(rank == receiver) 
    { 
     double littlearray[count]; 

     MPI_Status status; 

     MPI_Recv(littlearray, count, MPI_DOUBLE, sender, mytag, 
        MPI_COMM_WORLD, &status); 

     printf("[%d]: ", rank); 
     for (int i=0; i<count; i++) 
      printf("%lf ", littlearray[i]); 
     printf("\n"); 
    } 

    MPI_Finalize(); 

    return 0; 
} 

编译和运行提供了

$ mpicc -o vector vector.c -std=c99 
$ mpirun -np 2 ./vector 
[0]: 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 2.000000 0.000000 0.000000 0.000000 0.000000 3.000000 0.000000 0.000000 0.000000 0.000000 4.000000 0.000000 0.000000 0.000000 0.000000 5.000000 0.000000 0.000000 0.000000 0.000000 6.000000 0.000000 0.000000 0.000000 0.000000 7.000000 0.000000 0.000000 0.000000 0.000000 8.000000 0.000000 0.000000 0.000000 0.000000 9.000000 0.000000 0.000000 0.000000 0.000000 
[1]: 0.000000 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 9.000000 
+0

谢谢 - 非常感谢! – JessMcintosh 2013-03-18 18:34:16

+0

一个问题 - 我这样做,但它比发送整个数组慢。你愿意解释为什么吗?还有一种更有效的方法,因为我在一个循环中使用了数千次迭代。 – JessMcintosh 2013-03-18 21:03:13

+1

这取决于。如果数据量很小 - 因此消息的长度对通信时间没有太大贡献 - 那么选择相关位的额外开销可能是显而易见的;这将取决于网络层。还有实际创建,提交和释放类型的开销,但只需要完成一次,而不是每个消息一次,因此您可以在多次迭代中分摊。 – 2013-03-18 21:08:44