컴퓨터는 버스라는 전송 장치가 있다. 이는 물리 메모리에서 다른 장치(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 |