意外的MPI地址偏移量

时间:2017-01-13 15:43:25

标签: c++ mpi

在下面的代码中,我预计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

1 个答案:

答案 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将被对齐,在这种情况下不会添加填充。这同样适用于代码中的局部变量,并且一些编译器会将它们重新排列为代码优化过程的一部分。