Reputation: 6149
In the code below, I expected addr[2] - addr[1]
to be equal to 4x4=16
which is the answer given by block_count[1]*extent_int
. Why addr[2] - addr[1]
gives 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;
}
Output:
4 4
20 16
Upvotes: 1
Views: 134
Reputation: 74485
This has nothing to do with MPI. On architectures with flat address space (basically any modern OS) MPI_Get_address(&a, &b);
is equivalent to b = (MPI_Aint)&a;
You simply observe (as pointed out by @francis) your C++ compiler inserting padding in order to satisfy the default alignment rules for your platform. The rest is described in the answers to this question (the links provided by @francis).
There is a relatively simple rule to prevent misalignment and the associated increase in size of such structures: put (if possible) the biggest types at the beginning:
struct S
{
double point[4];
int a;
int nei[4];
};
Since the size of int
divides the size of double
, the int
s will be aligned and no padding will be added in that case. The same applies to the local variables in your code, and some compilers do rearrange them as part of the code optimisation process.
Upvotes: 1