반응형

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

__declspec( align( # ) ) declarator  

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

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

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

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

컴파일러는 복사 또는 데이터 변환 작업 중에 데이터의 맞춤 특성 보존을 보장하거나 시도하지 않습니다. 예를 들어 memcpy는 __declspec(align(#))로 선언된 구조체를 임의의 위치에 복사할 수 있습니다. malloc, C++ operator new 및 Win32 할당자와 같은 일반 할당자가 반환하는 메모리는 대개 __declspec(align(#)) 구조체 또는 구조체 배열에 사용할 수 있도록 충분히 맞춰지지 않은 상태입니다. 복사 또는 데이터 변환 작업의 대상이 올바르게 맞춰지도록 하려면 _aligned_malloc를 사용하거나 할당자를 직접 작성합니다.

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

__declspec(align(#))를 사용하지 않는 경우 Visual C++는 일반적으로 대상 프로세서와 데이터 크기를 기반으로 자연 경계에 데이터를 맞춥니다(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(#))는 맞춤 제한만 늘릴 수 있습니다.




맞춤 (C++)

Visual Studio 2015
 

Visual Studio 2017 에 대한 최신 설명서는 Visual Studio 2017 설명서를 참조하세요.

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는 aligned로 선언하는 데이터입니다.

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

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

컴파일러는 복사 또는 데이터 변환 작업 중에 데이터의 맞춤 특성 보존을 보장하거나 시도하지 않습니다. 예를 들어 memcpy는 __declspec(align(#))로 선언된 구조체를 임의의 위치에 복사할 수 있습니다. malloc, C++ operator new 및 Win32 할당자와 같은 일반 할당자가 반환하는 메모리는 대개 __declspec(align(#)) 구조체 또는 구조체 배열에 사용할 수 있도록 충분히 맞춰지지 않은 상태입니다. 복사 또는 데이터 변환 작업의 대상이 올바르게 맞춰지도록 하려면 _aligned_malloc를 사용하거나 할당자를 직접 작성합니다.

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

__declspec(align(#))를 사용하지 않는 경우 Visual C++는 일반적으로 대상 프로세서와 데이터 크기를 기반으로 자연 경계에 데이터를 맞춥니다(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(#))는 맞춤 제한만 늘릴 수 있습니다.

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

다음 예제에서는 __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바이트 패딩이 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바이트 맞춤입니다. sizeof를 사용해도 각 배열 멤버의 __declspec(align(#)) 값에 영향을 주지 않습니다.

CACHE_ALIGN int i; CACHE_ALIGN int array[128]; //배열의 경우에 32 바이트단위로 맞춤(끊어)정렬된다 CACHE_ALIGN struct s2 s;




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

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


반응형

+ Recent posts