align(C++)

Visual Studio 2015 이상에서는 지정자(C++11)를 사용하여 alignas 맞춤을 제어합니다. 자세한 내용은 맞춤을 참조 하세요.

Microsoft 전용

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

구문

__declspec( align(#) )declarator

설명

최신 프로세서 명령을 사용하는 애플리케이션을 작성할 경우 몇 가지 새로운 제약 조건과 문제가 생깁니다. 많은 새 지침을 사용하려면 데이터를 16비트 경계에 맞춰야 합니다. 자주 사용하는 데이터를 프로세서의 캐시 줄 크기에 맞추면 캐시 성능이 향상됩니다. 예를 들어 크기가 32바이트 미만인 구조를 정의하는 경우 32바이트 맞춤을 통해 해당 구조체 형식의 개체가 효율적으로 캐시되도록 할 수 있습니다.

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

형식의 맞춤 요구 사항인 형식 size_t 값을 반환하는 방법에 대한 자세한 내용은 다음을 참조하세요 alignof. 64비트 프로세서를 대상으로 할 때 정렬되지 않은 포인터를 선언하는 방법에 대한 자세한 내용은 다음을 참조하세요 __unaligned.

또는 변수를 정의할 때 또는 class변수를 unionstruct선언할 때 사용할 __declspec(align(#)) 수 있습니다.

컴파일러는 복사 또는 데이터 변환 작업 중에 데이터의 맞춤 특성을 보장하거나 유지하려고 시도하지 않습니다. 예를 들어 memcpy 선언된 __declspec(align(#)) 구조체를 모든 위치에 복사할 수 있습니다. 일반 할당자(예: mallocC++ operator new및 Win32 할당자)는 일반적으로 구조체 또는 구조 배열에 __declspec(align(#)) 대해 정렬되지 않은 메모리를 반환합니다. 복사 또는 데이터 변환 작업의 대상이 올바르게 정렬되도록 하려면 다음을 사용합니다 _aligned_malloc. 또는 고유한 할당자를 작성합니다.

함수 매개 변수에 대한 맞춤을 지정할 수 없습니다. 스택의 값으로 맞춤 특성이 있는 데이터를 전달하면 호출 규칙이 해당 맞춤을 제어합니다. 호출된 함수에서 데이터 맞춤이 중요한 경우에는 사용 전에 매개 변수를 올바르게 맞춰진 메모리로 복사합니다.

컴파일 __declspec(align(#))러는 일반적으로 대상 프로세서 및 데이터 크기에 따라 자연 경계에 데이터를 정렬하고, 32비트 프로세서에서 최대 4 바이트 경계를, 64비트 프로세서에서 8 바이트 경계를 정렬합니다. 클래스 또는 구조체의 데이터는 클래스 또는 구조체에서 자연 맞춤 및 현재 압축 설정(원본 #pragma pack 또는 컴파일러 옵션)의 최소값으로 /Zp 정렬됩니다.

이 예제에서는 __declspec(align(#))의 사용을 보여 줍니다.

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

현재 이 형식에는 32비트 맞춤 특성이 포함되어 있습니다. 즉, 모든 정적 및 자동 인스턴스는 32비트 경계에서 시작됩니다. 이 형식을 멤버로 선언한 다른 구조체 형식은 이 형식의 맞춤 특성을 유지합니다. 즉, 요소로 포함된 Str1 모든 구조체에는 맞춤 특성이 32개 이상 있습니다.

여기서는 sizeof(struct Str1) 32와 같습니다. 개체 배열이 만들어지고 배열의 Str1 기준이 32 바이트 정렬되면 배열의 각 멤버도 32 바이트 정렬됩니다. 기본이 동적 메모리에 올바르게 정렬된 배열을 만들려면 .를 사용합니다 _aligned_malloc. 또는 고유한 할당자를 작성합니다.

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

컴파일러는 구조체 맞춤에 다음과 같은 규칙을 사용합니다.

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

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

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

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

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

자세한 내용은 다음을 참조하세요.

align 예제

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

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

이 예제에서는 S1를 사용하여 __declspec(align(32)) 구조체를 정의합니다. 변수 정의에 대해 또는 기타 형식 선언에서 사용되는 모든 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

이 예제에서는 최대 맞춤 요구 사항의 배수가 8의 배수인 16이므로 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바이트 패딩이 뒤따 as1 오프셋 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 바이트 정렬됩니다. 각 배열 멤버의 값은 sizeof 사용할 __declspec(align(#))때 영향을 받지 않습니다.

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의 맞춤, 할당 및 크기 특성이 동일합니다.

이 예제에서는 각각 , , bcd 4, 1, 4 및 1의 a시작 주소 맞춤입니다.

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

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

를 사용하여 새 형식 정의 __declspec(align(#))

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

예를 들어 다음과 같이 맞춤 값을 사용하여 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;

데이터 압축 작동 방법 align

/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 전용 종료

참고 항목

__declspec
ARM ABI 규칙 개요
x64 소프트웨어 규칙