C++ 使数据连续以在节点之间传输的有效方法 结构面 { //Matrixd是二维矩阵的一维表示 std::数组M; }; 向量面;

C++ 使数据连续以在节点之间传输的有效方法 结构面 { //Matrixd是二维矩阵的一维表示 std::数组M; }; 向量面;,c++,mpi,contiguous,C++,Mpi,Contiguous,我在节点之间有一个分布式for循环。在所有节点完成对其元素的处理后,我希望在节点之间传输相应的元素。但是可以使用MPI\u Allgatherv数据应该是连续的。首先,我切换到2D矩阵的一维表示(之前我使用的是[][]符号)。现在我想使face.M成为连续的。我正在考虑将M[0]的所有元素复制到一个std::array节点之间的传输。这条路有效吗?为了了解我处理的数据数量,如果我有20k个单元格,那么最多有20k*3=60k个面。我可能也有一百万个单元格。在C/C++中,一个真正的2D数组,例如

我在节点之间有一个分布式for循环。在所有节点完成对其元素的处理后,我希望在节点之间传输相应的元素。但是可以使用
MPI\u Allgatherv
数据应该是连续的。首先,我切换到2D矩阵的一维表示(之前我使用的是[][]符号)。现在我想使
face.M
成为连续的。我正在考虑将M[0]的所有元素复制到一个
std::array
节点之间的传输。这条路有效吗?为了了解我处理的数据数量,如果我有20k个单元格,那么最多有20k*3=60k个面。我可能也有一百万个单元格。

在C/C++中,一个真正的2D数组,例如
intfoo[5][5]
在内存中已经是连续的;它基本上只是
intfoo[25]
的语法糖,其中像
foo[3][2]
这样的访问隐式地查找
foo[3*5+2]
。切换到单个维度中定义的
矩阵xd
不会改变实际内存布局

std::array
也(大部分)只是C风格数组的包装器;如果没有虚拟成员,编译时定义的大小没有内部指针(只有原始数组),那么它也将是连续的。我强烈怀疑,如果您检查生成的程序集,您会发现
Matrixd
s的
array
已经是连续的


简言之,我认为你不需要改变任何事情;您已经是连续的,所以MPI应该是可以的。

M
是连续的,但我想将
face.M
s的数量设置为连续的,以便作为一个束发送/接收,而不是逐个发送/接收。至少在C++03中是这样的:元素是连续存储的,这意味着不仅可以通过迭代器访问元素,还可以使用指向元素的常规指针上的偏移量来访问元素。这意味着指向向量元素的指针可以传递给任何需要指向数组元素的指针的函数。“因此,
M
s不连续的唯一原因是结构由于对齐相关的原因需要填充(考虑到设计,这似乎不太可能)@Shibli:std::vector将元素存储在一行中,因此您得到了continuous
vector
的continuous
struct
的continuous
数组
的continuous
Matrixd
。您已经是黄金了(使用向量中的值时,不要更改向量的大小或调用
reserve
,否则重新分配可能会使指向
向量的指针无效
)。如果
向量
存储了
面*
面&
而不是实际的
,则只会丢失连续行为。因此,当我使用say
MPI\u Send时,
如果我将指针指向
面[0]。M[0][0][0]
作为一个参数,并将元素数作为另一个参数等,该函数是否可以正常工作?@Shibli:同样,可能会出现对齐/填充问题,因此您需要根据单个
面的编译时计算大小来计算要传输的字节数
,但如果传递
面[0].M[0][0]
和长度为
numelements*sizeof(face[0])
或其他任何东西,都应该考虑到这一点。见鬼,传递
&face[0]
应该可以,不需要
.M[0][0][0]
struct Face
{
    // Matrixd is 1D representation of 2D matrix
    std::array < Matrixd<5,5>, 2 > M;
};

std::vector <Face> face;