2017-01-13 1 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이 정렬되고이 경우 패딩이 추가되지 않습니다. 코드의 로컬 변수도 마찬가지이며 일부 컴파일러는 코드 최적화 프로세스의 일부로이를 다시 정렬합니다.