2017-01-13 5 views
1

以下のコードでは、の回答である4x4=16と等しいと予想しています。なぜaddr[2] - addr[1]は20?予期しないMPIアドレスオフセット

#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

これは整列に関連しているようです。 http://stackoverflow.com/questions/11108328/double-alignmentを参照してください。特に、['x86-64では、-malign-doubleはデフォルトで有効になっています.']](https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html)ここでは、 doubleの配列は8バイトの倍数である24バイトです。 – francis

答えて

1

これは、MPIとは何の関係もありません。フラットなアドレス空間を持つアーキテクチャ(基本的には現代のOS)MPI_Get_address(&a, &b);b = (MPI_Aint)&a;に相当します。あなたのプラットフォームのデフォルトの配置規則を満たすために、C++コンパイラがパディングを挿入することを(@ francisが指摘する)単純に観察します。残りはthis question(@francisが提供するリンク)への回答に記載されています。 intのサイズがサイズを分割しているので

struct S 
{ 
    double point[4]; 
    int a; 
    int nei[4]; 
}; 

:先頭に置く(可能な場合)の最大のタイプ:ずれを防ぐために、比較的単純なルールと、このような構造体のサイズの関連する増加がある

doubleの場合、intが整列され、その場合はパディングは追加されません。これはコード内のローカル変数にも当てはまりますが、コード最適化プロセスの一部としてそれらを再配置するコンパイラもあります。

関連する問題