본문 바로가기
코드

alignas

by ehei 2021. 2. 3.

컴퓨터는 버스라는 전송 장치가 있다. 이는 물리 메모리에서 다른 장치(CPU, 다른 메모리 등)로 데이터를 전송하는데 쓰이는 선로이다. 도로와 비견되며 버스의 대역폭-한꺼번에 전송 가능한 크기-이 클수록 정보를 더 빠르게 전달할 수 있다. 그렇다면 대역폭보다 전송할 데이터의 크기가 작다면 어떻게 될까? 유감스럽게도 그렇더라도 그대로 전송한다. 이렇게 대역폭에서 쓰지 않는 만큼을 패딩이라고 한다. 대역폭과 자료형을 맞추면 추가적인 처리가 필요없어 더 빠르게 전송할 수 있다.

C11부터 포함된 alignas는 구조체가 효율적인 크기를 갖도록 컴파일러 차원에서 강제해준다.

// C11
struct alignas(16) float4 {
    float r;
    float g;
    float b;
    float a;
};

// MSVC
struct __declspec(align(#16)) float4 {
    float r;
    float g;
    float b;
    float a;
};


alignas 등 한정자를 설정하고 이를 지키지 않으면 경고가 표시된다.

C4324: '...': 맞춤 지정자 때문에 구조체가 채워졌습니다

이 쓰임새는 DirectX에서 발견할 수 있다. Device::SetTransform()를 호출할 때 16바이트로 정렬된 D3DXMATRIXA16 대신 D3DXMATRIX를 사용할 경우 성능 경고가 표시된다. DirectX 9의 경우 DxDialg에서 설정했더라도 Windows 7 환경에서만 볼 수 있다.

D3DX: Matrix should be 16-byte aligned for better performance

 

문제는 이것을 사용자가 정의한 클래스/구조체의 멤버 변수로 선언했을때도 같은 경고를 표시한다는 점이다.  이를 피하려면 패딩 바이트를 지정해줘야 한다. 포인터로 사용하는 방법도 있다.

struct parent {
    float v;
};

struct child : public parent {
    // 없으면 경고
    char _[sizeof( m ) - sizeof( parent )];

    D3DXMATRIXA16 m;
};


https://en.cppreference.com/w/cpp/language/alignas
https://docs.microsoft.com/ko-kr/cpp/cpp/align-cpp?view=msvc-160

http://telnet.or.kr/directx/graphics/reference/d3dx/structures/d3dxmatrixa16.htm

 

 

'코드' 카테고리의 다른 글

위치 지정 new  (0) 2021.02.17
메모리  (0) 2021.02.15
make_index_sequence 구현  (0) 2021.01.27
tuple 출력  (0) 2021.01.22
std::remove_if  (0) 2021.01.21