在下面的代码中,我预计addr[2] - addr[1]
等于4x4=16
,这是block_count[1]*extent_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;
}
输出:
4 4
20 16
答案 0 :(得分:1)
这与MPI无关。在具有平面地址空间的架构上(基本上是任何现代操作系统)MPI_Get_address(&a, &b);
等同于b = (MPI_Aint)&a;
您只需观察(由@francis指出)您的C ++编译器插入填充以满足默认的对齐规则你的平台。其余部分在this question(@francis提供的链接)的答案中描述。
有一个相对简单的规则可以防止错位以及此类结构的相应增加:在开头放置(如果可能)最大的类型:
struct S
{
double point[4];
int a;
int nei[4];
};
由于int
的大小除以double
的大小,int
将被对齐,在这种情况下不会添加填充。这同样适用于代码中的局部变量,并且一些编译器会将它们重新排列为代码优化过程的一部分。