2010-12-14 3 views
5

한 줄의 코드는 여기에 :) 천 개 단어의 가치가 내 문제는 다음과 같습니다C++ 메모리 정렬 질문

/* Platform specific 16-byte alignment macro switch. 
    On Visual C++ it would substitute __declspec(align(16)). 
    On GCC it substitutes __attribute__((aligned (16))). 
*/ 
#define ALIGN_16 ... 

struct ALIGN_16 A {...}; 

A* ptr = new A; 
A* ptr2 = new A[20]; 

assert(size_t(ptr) % 16 == 0); 

for (int i=0; i<20; ++i) 
    assert(size_t(ptr2+i) % 16 == 0); 

assert(sizeof(A) % 16 == 0); 

나는 모든 주장은 SSE를 지원하는 플랫폼에 전달할 것으로 예상 할 수 있습니까? 고맙습니다.

EDIT. 부분적인 대답. VS2008, GCC 및 ICC로 몇 가지 테스트를 수행했습니다. MS 컴파일러는 ptrptr2을 모두 정렬했지만 GCC와 ICC는 ptr2을 정렬하지 못했습니다.

+0

왜 (20)의 배열 같이? – John

+0

그냥 내 머리에서. 배열의 모든 요소가 정렬되어 있다면 방황하고있었습니다. – watson1180

+2

적절히 할당 된 배열의 요소는 해당 유형에 맞게 올바르게 정렬되도록 표준에 의해 보장됩니다. 그러나이 정렬은 구현 세부 사항이며 이론적으로 1 바이트 (즉, 묶음 정렬)가 될 수 있습니다. –

답변

4

Is there any guarantee of alignment of address return by C++'s new operation?

은 즉, 당신은 일을해야한다는 당신의 가정을 정당화하기 위해 표준을 사용할 수 있지만 실제로, 그것은 당신의 얼굴에 날려 버릴 수 있습니다.

Visual C++ 6은 을 new을 통해 올바르게 할당하지 않았으므로 여기로 이동했습니다.

std::aligned_storage<Length, Alignment> 

항상 정확하게 늘어나는만큼 정렬을 보장 :

+0

최신 컴파일러는 어떻습니까? GCC 4.xx 및 VS 2008? – watson1180

+1

16 바이트 정렬에'new' 또는'malloc'을 제공하는 컴파일러에 대해서는 알지 못합니다. 즉, 실제로는 어설 션이 실패합니다. – jalf

+0

@ jalf, 그래, 그게 내가 생각한거야. C++ 0x에서 "지원"한다고 가정하지만, HeapAlloc은 간접적으로 8 바이트를 보장합니다 (기본 패킹 옵션은 Windows 데이터 구조의 경우 8 바이트 정렬이므로), 나는 이것이 언제든지 곧 발생할 것이라고 생각하지 않습니다. – MSN

1

C++ 0X은 ([meta.type.synop]20.7.6.6 다른 변환에서) 새로운 구조를 제공한다 나는 회상한다.

두 번째 매개 변수는 선택 사항이며 가능한 가장 엄격한 요구 사항을 기본값으로 사용합니다 (정확한 값은 아니더라도 항상 안전하지만 시도 할 경우 유형을 더 압축 할 수 있습니다).

bugs 외에도 컴파일러는 요구 사항을 준수해야합니다. C++ 0x가 없으면 tr1 네임 스페이스 또는 Boost에 있습니다.

당신은 특정 컴파일러가이 요청을 :) 명예 않음을 테스트 할 수있는 유일한 사람이야

참고 : gcc-4.3.2에, 그것은으로 구현됩니다 :

template<std::size_t _Len, std::size_t _Align = /**/> 
struct aligned_storage 
{ 
    union type 
    { 
    unsigned char __data[_Len]; 
    struct __attribute__((__aligned__((_Align)))) { } __align; 
    }; 
}; 
+0

객체는 'new'로 할당됩니다. 일반적으로 특정 정렬 요구 사항을 따르지는 않습니다. (일반적으로 대부분의 경우 8 바이트 정렬 메모리를 제공합니다.) – jalf

+0

@jalf : 표준에서는'new'가 적절히 정렬 된 메모리 조각을 반환하도록 요구합니다 (3.7.4.1 [basic.std.dynamic .allocation] $ 2), 기본 정렬 요구 사항 (3.11) * 및 3.11 [기본.]을 가진 모든 완전한 개체 형식의 포인터로 변환 할 수 있도록 *를 이해하지 않는 한.정렬] $ 2 * 기본 정렬은 모든 문맥에서 구현이 지원하는 최대 정렬보다 작거나 같은 정렬로 표현되며, 이는 alignof (std :: max_align_t) (18.2)와 같습니다. * –

+0

... 따라서 'new'가 8 바이트 정렬 값만을 리턴하고'std :: max_align_t'가 8보다 우수한 경우, 구현은 부적합합니다. –