2013-05-18 48 views
2

MPI應用程序中,我有一個浮點數分佈式數組和兩個「並行」整數數組:對於每個浮點值,都有兩個相關的整數描述對應的值。爲了提高緩存效率,我想將它們看作三個不同的數組,即作爲數組的結構,而不是結構數組。用於數組結構的MPI數據類型

現在,我必須將所有這些值收集到第一個節點。我可以在一條通信指令中做到這一點,通過定義一個對應於結構的MPI類型,其中包含一個浮點數和兩個整數。但是這會迫使我使用結構模式數組而不是數組結構。

所以,我可以選擇之間:

  • 執行三個不同的通信,一個用於每個陣列和保持陣列排列
  • 的高效的結構定義一個MPI類型,執行一個單一的通信,和處理通過調整我的算法或者重新排列數據

結構的結果數組你知道有一個單一的通信的第三個選擇,讓我確實有兩全其美的,即nd保持緩存高效的配置?

回答

0

E.g.通過使用* array_of_blocklength *的MPI_Type_create_struct

// @file mpi_compound.cpp 
#include <iterator> 
#include <cstdlib> // for rng 
#include <ctime> // for rng inits 
#include <iostream> 
#include <algorithm> 

#include <mpi.h> 

const std::size_t N = 10; 

struct Asset { 
    float f[N]; 
    int m[N], n[N]; 

    void randomize() { 
     srand(time(NULL)); 
     srand48(time(NULL)); 
     std::generate(&f[0], &f[0] + N, drand48); 
     std::generate(&n[0], &n[0] + N, rand); 
     std::generate(&m[0], &m[0] + N, rand); 
    } 
}; 


int main(int argc, char* argv[]) { 

    MPI_Init(&argc,&argv); 
    int rank,comm_size; 
    MPI_Status stat; 

    MPI_Comm_rank(MPI_COMM_WORLD,&rank); 
    MPI_Comm_size(MPI_COMM_WORLD,&comm_size); 

    Asset a; 

    MPI_Datatype types[3] = { MPI_FLOAT, MPI_INT, MPI_INT }; 
    int bls[3] = { N, N, N }; 
    MPI_Aint disps[3]; 
    disps[0] = 0; 
    disps[1] = int(&(a.m[0]) - (int*)&a)*sizeof(int); 
    disps[2] = int(&(a.n[0]) - (int*)&a)*sizeof(int); 

    MPI_Datatype MPI_USER_ASSET; 

    MPI_Type_create_struct(3, bls, disps, types, &MPI_USER_ASSET); 
    MPI_Type_commit(&MPI_USER_ASSET); 

    if(rank==0) { 
     a.randomize(); 
     std::copy(&a.f[0], &a.f[0] + N, std::ostream_iterator<float>(std::cout, " ")); 
     std::cout << std::endl; 
     std::copy(&a.m[0], &a.m[0] + N, std::ostream_iterator<int>(std::cout, " ")); 
     std::cout << std::endl; 
     std::copy(&a.n[0], &a.n[0] + N, std::ostream_iterator<int>(std::cout, " ")); 
     std::cout << std::endl; 
     MPI_Send(&a.f[0],1,MPI_USER_ASSET,1,0,MPI_COMM_WORLD); 
    } else { 
     MPI_Recv(&a.f[0],1,MPI_USER_ASSET,0,0,MPI_COMM_WORLD, &stat); 
     std::cout << "\t=> "; 
     std::copy(&a.f[0], &a.f[0] + N, std::ostream_iterator<float>(std::cout, " ")); 
     std::cout << std::endl << "\t=> "; 
     std::copy(&a.m[0], &a.m[0] + N, std::ostream_iterator<int>(std::cout, " ")); 
     std::cout << std::endl << "\t=> "; 
     std::copy(&a.n[0], &a.n[0] + N, std::ostream_iterator<int>(std::cout, " ")); 
     std::cout << std::endl; 
    } 

    MPI_Type_free(&MPI_USER_ASSET); 

    MPI_Finalize(); 
    return 0; 
} 

參數曾與

mpirun -n 2 ./mpi_compound 

與x86_86的Linux和g ++ 4.4.5-8 MPICH2 V1.5(HYDRA) - 基於MPIC++