2013-03-18 46 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