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

+0

한 가지 질문 - 전체 배열을 보내는 것보다 속도가 느립니다. 이유를 설명해 주시겠습니까? 또한 반복적으로 수천 회 반복되는 루프에서이 방법을 사용하기 때문에보다 효율적인 방법이 있습니다. – JessMcintosh

+1

달라집니다. 데이터가 어느 쪽이든 작은 경우 - 메시지 길이가 통신 시간에 크게 기여하지 않는 경우 관련 비트 만 선택하는 추가 오버 헤드가 눈에 띄게 될 수 있습니다. 네트워크 계층에 따라 다릅니다. 또한 실제로 유형을 작성, 커밋 및 해제하는 오버 헤드가 있지만 메시지 당 한 번만 수행하면되므로 많은 반복을 통해 상환 할 수 있습니다. –