在MPI
应用程序中,我有一个分布式浮点数组和两个" parallel"整数数组:对于每个浮点值,有两个关联的整数来描述相应的值。为了提高缓存效率,我想将它们视为三个不同的数组,即作为数组的结构,而不是结构数组。
现在,我必须将所有这些值收集到第一个节点中。我可以在一个通信指令中完成此操作,方法是定义一个MPI
类型,对应一个结构,一个浮点数和两个整数。但这会迫使我使用结构模式数组而不是数组结构。
所以,我可以选择:
MPI
类型,执行单个通信,并通过调整算法或重新排列数据来处理生成的结构数组您是否知道第三种方案可以让我充分利用这两个方面,即进行单一通信并保持缓存高效配置?
答案 0 :(得分:0)
您可以看看包装和拆包。
http://www.mpi-forum.org/docs/mpi-11-html/node62.html
但是,我认为如果你想经常传递一个相同的“结构”,你应该定义自己的MPI派生类型。
答案 1 :(得分:0)
E.g。使用MPI_Type_create_struct
的* array_of_blocklength *参数// @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上使用mpich2 v1.5(HYDRA)和基于g ++ 4.4.5-8的mpic ++