내보내기(0) 인쇄
모두 확장
이 문서는 기계로 번역한 것입니다. 원본 텍스트를 보려면 포인터를 문서의 문장 위로 올리십시오. 추가 정보
번역
원본

맞춤 (C++)

Microsoft 전용

__declspec(align(#))를 사용하여 사용자 정의 데이터(예: 함수의 정적 할당 또는 자동 데이터)를 정확하게 제어합니다.

맞춤에 대한 자세한 내용은 IPF의 Windows 데이터 맞춤, x86 및 x64를 참조하십시오.

__declspec( align( # ) ) declarator

최신 프로세서 명령을 사용하는 응용 프로그램을 작성할 경우 몇 가지 새로운 제약 조건과 문제가 생깁니다. 특히 새로운 명령을 사용할 때 데이터를 16바이트 경계에 맞춰야 하는 경우가 많습니다. 또한 자주 사용하는 데이터를 특정 프로세서의 캐시 줄 크기에 맞춤으로써 캐시 성능이 향상됩니다. 예를 들어, 크기가 32바이트 미만인 구조체를 정의할 경우 해당 구조체 형식의 개체가 효과적으로 캐시되도록 이 구조체를 32바이트에 맞출 수 있습니다.

#은 맞춤 값입니다. 유효한 항목은 2, 4, 8, 16, 32 또는 64와 같이 1에서 8192(바이트) 사이에 속하는 2의 정수 제곱입니다. declarator는 aligned로 선언하는 데이터입니다.

해당 형식의 맞춤 요구 사항인 size_t 형식의 값을 반환하는 방법에 대한 자세한 내용은 __alignof를 참조하고, 64비트 프로세서를 대상으로 맞춰지지 않은 포인터를 선언하는 방법에 대한 자세한 내용은 __unaligned를 참조하십시오.

struct , union 또는 class를 정의하거나 변수를 선언할 때 __declspec(align(#))를 사용할 수 있습니다.

__declspec(align(#))를 사용하지 않으면 Visual C++가 데이터 크기에 따라 자연 경계에 데이터를 맞춥니다(예: 4바이트 경계에 4바이트 정수, 8바이트 경계에 8바이트 doubles). 클래스 또는 구조체 안의 데이터는 최소한의 자연 맞춤 및 현재의 압축 설정(#pragma pack 또는 /Zp 컴파일러 옵션에서)으로 클래스나 구조체 안에 정렬됩니다.

함수 매개 변수의 맞춤을 지정할 수 없습니다.

예를 들면 다음과 같습니다.

__declspec(align(32)) struct Str1{
   int a, b, c, d, e;
};

현재 이 형식에는 32비트 맞춤 특성이 있어 모든 인스턴스가 32바이트 경계에서 시작됩니다. 이 형식을 사용하여 멤버로 선언된 추가 구조체 형식은 이 형식의 맞춤 특성을 유지하여 Str1이 요소로 지정된 모든 구조체는 32 이상의 맞춤 특성을 갖게 됩니다.

요약하면 다음과 같습니다.

  • __declspec(align(#))로 재정의하지 않으면 스칼라 구조체 멤버의 맞춤은 최소 크기와 현재 압축입니다.

  • __declspec(align(#))로 재정의하지 않으면 구조체의 멤버는 멤버의 최대 개별 맞춤입니다.

  • 구조체 멤버는 이전 멤버 끝의 오프셋보다 크거나 같은 맞춤의 최소 배수인 부모 구조체의 시작 부분부터 오프셋에 배치됩니다.

  • 구조체의 크기는 마지막 멤버의 오프셋 끝보다 크거나 같은 맞춤의 최소 배수입니다.

sizeof(struct Str1)는 32입니다. Str1 개체의 배열이 만들어지고 배열의 기본이 32바이트 맞춤일 경우 배열의 각 멤버도 32바이트 맞춤이 됩니다. 기본이 제대로 맞춰진 배열을 만들려면 _aligned_malloc를 사용하거나 할당자를 직접 작성합니다. malloc 등의 일반 할당자, C++ operator new 및 Win32 할당자는 __declspec(align(#)) 구조체나 구조체의 배열에 대해 충분히 정렬되지 않을 가능성이 큰 메모리를 반환합니다.

구조체의 sizeof 값은 최종 멤버의 오프셋에 해당 멤버의 크기를 더하여 최대 멤버 맞춤 값 또는 전체 구조체 맞춤 값 중 큰 값의 가장 근사한 배수로 반올림한 값입니다.

__declspec(align(#))는 맞춤 제한만 늘릴 수 있습니다.

자세한 내용은 다음을 참조하십시오.

다음 예제에서는 __declspec(align(#))가 데이터 구조체의 크기 및 맞춤에 영향을 주는 방식을 보여 줍니다. 예제에서는 다음과 같은 정의를 가정합니다.

#define CACHE_LINE  32
#define CACHE_ALIGN __declspec(align(CACHE_LINE))

다음 예제에서 __declspec(align(32))를 사용하여 S1 구조체가 정의됩니다. 변수 정의나 다른 형식 선언에 S1을 사용할 때마다 이 구조체 데이터는 32바이트 맞춤입니다. sizeof(struct S1)는 32를 반환하고 S1은 16바이트 뒤에 정수 4개에 필요한 16 패딩 바이트를 둡니다. int 멤버에 4바이트 맞춤이 필요하지만 구조체 자체의 맞춤은 32로 선언되므로 전체 맞춤은 32입니다.

struct CACHE_ALIGN S1 { // cache align all instances of S1
   int a, b, c, d;
};
struct S1 s1;   // s1 is 32-byte cache aligned

다음 예제에서는 최대 맞춤 요구 사항의 배수가 16이므로(8의 배수) sizeof(struct S2)는 멤버 크기의 합계와 똑같은 16을 반환합니다.

__declspec(align(8)) struct S2 {
   int a, b, c, d;
};

다음 예제에서 sizeof(struct S3)는 64를 반환합니다.

struct S3 {
   struct S1 s1;   // S3 inherits cache alignment requirement
                  // from S1 declaration
   int a;         // a is now cache aligned because of s1
                  // 28 bytes of trailing padding
};

다음 예제에서 a에 자연 형식의 맞춤만 있으며 이 경우 4바이트입니다. 그러나 S1은 32바이트 맞춤이어야 합니다. 28바이트 패딩이 a 뒤에 나와 s1이 32 오프셋에서 시작됩니다. 그런 다음 S4가 구조체의 최대 맞춤 요구 사항인 S1의 맞춤 요구 사항을 상속합니다. sizeof(struct S4)가 64를 반환합니다.

struct S4 {
   int a;
   // 28 bytes padding
    struct S1 s1;      // S4 inherits cache alignment requirement of S1
};

다음 3개의 변수 선언에도 __declspec(align(#))가 사용됩니다. 각 선언에서 변수가 32바이트 맞춤이어야 합니다. 배열의 경우 각 배열 멤버가 아니라 배열의 기준 주소가 32바이트 맞춤입니다. __declspec(align(#))를 사용해도 각 배열 멤버의 sizeof 값에 영향을 주지 않습니다.

CACHE_ALIGN int i;
CACHE_ALIGN int array[128];
CACHE_ALIGN struct s2 s;

배열의 개별 멤버를 각각 맞추려면 다음과 같은 코드를 사용해야 합니다.

typedef CACHE_ALIGN struct { int a; } S5;
S5 array[10];

다음 예제에서 구조체 자체를 맞추는 것과 첫 번째 요소를 맞추는 것은 동일합니다.

CACHE_ALIGN struct S6 {
   int a;
   int b;
};

struct S7 {
   CACHE_ALIGN int a;
               int b;
};

S6S7의 맞춤, 할당 및 크기 특성이 동일합니다.

다음 예제에서 a, b, c, d의 시작 주소 맞춤은 각각 4, 1, 4, 1입니다.

void fn() { 
   int a;
   char b;
   long c;
   char d[10]
} 

메모리가 힙에 할당된 경우 호출되는 할당 함수에 따라 맞춤이 결정됩니다. 예를 들어, malloc를 사용할 경우 피연산자 크기에 따라 결과가 결정됩니다. arg >= 8이면 맞춤이 8바이트 맞춤이 됩니다. arg < 8이면 arg보다 작은 2의 첫 번째 거듭제곱이 맞춤입니다. 예를 들어, malloc(7)를 사용하면 맞춤이 4바이트입니다.

맞춤 특성을 사용하여 형식을 정의할 수 있습니다.

예를 들어, 다음과 같이 맞춤 값을 사용하여 struct를 정의할 수 있습니다.

struct aType {int a; int b;};
typedef __declspec(align(32)) struct aType bType;

이제 aTypebType의 크기가 같지만(8바이트) bType 형식의 변수는 32바이트 맞춤입니다.

__declspec(thread) 특성으로 만들어 이미지의 TLS 섹션에 넣은 정적 TLS(스레드 로컬 저장소)는 보통의 정적 데이터와 똑같은 맞춤으로 작동합니다. 운영 체제에서 TLS 섹션의 데이터 크기를 할당하고 TLS 섹션 맞춤 특성을 고려하여 TLS 데이터를 만듭니다.

다음 예제에서는 정렬된 데이터를 스레드 로컬 저장소에 배치하는 여러 가지 방법을 보여 줍니다.

// put an aligned integer in TLS
__declspec(thread) __declspec(align(32)) int a;   

// define an aligned structure and put a variable of the struct type
// into TLS
__declspec(thread) __declspec(align(32)) struct F1 { int a; int b; } a;

// create an aligned structure 
struct CACHE_ALIGN S9 {
   int a;
   int b;
};
// put a variable of the structure type into TLS
__declspec(thread) struct S9 a;

/Zp 컴파일러 옵션과 pack pragma는 구조체 및 공용 구조체 멤버의 압축 데이터 역할을 합니다. 이 예제에서는 /Zp__declspec(align(#))가 함께 작동하는 방법을 보여 줍니다.

struct S {
   char a;
   short b;
   double c;
   CACHE_ALIGN double d;
   char e;
   double f;
};

다음 표에서는 여러 /Zp(또는 #pragma pack)에 속한 각 멤버의 오프셋을 나열하고 둘 사이의 상호 작용 방식을 보여 줍니다.

변수

/Zp1

/Zp2

/Zp4

/Zp8

a

0

0

0

0

b

1

2

2

2

c

3

4

4

8

d

32

32

32

32

e

40

40

40

40

f

41

42

44

48

sizeof(S)

64

64

64

64

자세한 내용은 /Zp(구조체 멤버 맞춤)을 참조하십시오.

따라서 개체에 __declspec(align(#)) 특성이 있고 맞춤이 이전 개체 및 개체의 __declspec(align(#)) 값을 기반으로 하지 않으면 개체의 오프셋이 이전 개체의 오프셋과 현재 압축 설정을 기반으로 합니다.

커뮤니티 추가 항목

추가
Microsoft는 MSDN 웹 사이트에 대한 귀하의 의견을 이해하기 위해 온라인 설문 조사를 진행하고 있습니다. 참여하도록 선택하시면 MSDN 웹 사이트에서 나가실 때 온라인 설문 조사가 표시됩니다.

참여하시겠습니까?
표시:
© 2014 Microsoft