C++ 意外的MPI地址偏移
在下面的代码中,我希望C++ 意外的MPI地址偏移,c++,mpi,C++,Mpi,在下面的代码中,我希望addr[2]-addr[1]等于4x4=16,这是由block\u count[1]*extent\u int给出的答案。为什么addr[2]-addr[1]20 #include <mpi.h> #include <iostream> struct S { int a; int nei[4]; double point[4]; }; int main() { MPI_Init(NULL, NULL);
addr[2]-addr[1]
等于4x4=16
,这是由block\u count[1]*extent\u int
给出的答案。为什么addr[2]-addr[1]
20
#include <mpi.h>
#include <iostream>
struct S
{
int a;
int nei[4];
double point[4];
};
int main()
{
MPI_Init(NULL, NULL);
S s;
int nblock = 3;
// block count.
int block_count[nblock] = {1, 4, 4};
// extent.
MPI_Aint lb, extent_int;
MPI_Type_get_extent(MPI_INT, &lb, &extent_int);
// offset.
MPI_Aint addr[nblock];
MPI_Get_address(&s.a, &addr[0]);
MPI_Get_address(&s.nei[0], &addr[1]);
MPI_Get_address(&s.point[0], &addr[2]);
//
std::cout << addr[1]-addr[0] << " " << block_count[0]*extent_int << std::endl;
std::cout << addr[2]-addr[1] << " " << block_count[1]*extent_int << std::endl;
MPI_Finalize();
return 0;
}
这与MPI无关。在具有平坦地址空间(基本上是任何现代操作系统)的体系结构上
MPI\u Get\u address(&a和&b)代码>相当于b=(MPI_Aint)&a代码>您只需观察(如@弗兰西斯指出的)C++编译器插入填充,以满足平台的默认对齐规则。其余部分在(由@francis提供的链接)的答案中进行了描述
有一个相对简单的规则来防止此类结构的错位和相关尺寸的增加:在开始时放置(如果可能)最大的类型:
struct S
{
double point[4];
int a;
int nei[4];
};
由于int
的大小除以double
的大小,因此int
将对齐,在这种情况下不会添加填充。这同样适用于代码中的局部变量,一些编译器会在代码优化过程中重新排列它们。这似乎与对齐有关。看见特别是在这里,结构开头和double数组之间的空间是24字节,是8的倍数。
struct S
{
double point[4];
int a;
int nei[4];
};