아래와 같이 컴파일 시, warning C4316을 뱉어낸다는 문제가 발생했습니다.
alignment error(C4316)은 무엇인가!?!?
위 경고는 __declspec(align(byte))로 정렬돼야 하는 데이터를 멤버로 가지거나, 할당할 때 생기는 경고입니다.
오류나는 부분을 점검해보면 XMMATRIX 변수부분에 대한 에러가 발생하는데 다음과 같습니다.
정의 부분을 보면 __declspec(align(16))으로 16바이트 정렬을 사용한다고 명시되어 있습니다. 이는 자주 사용되는 데이터를 특정 프로세서 캐시라인 크기로 정렬하여 한꺼번에 계산하여 CPU 캐시 처리 성능을 높여줍니다.
게임 프로그래밍에 사용되는 행렬 연산을 고속으로 한꺼번에 처리하기 위해서 SSE라는 새로운 명령어 집합이 생겨나게 되면서 이러한 바이트 정렬 연산이 사용되게 된 것입니다.
그런데 이는 스텍에선 별 문제가 되지 않지만, HEAP에 할당할 때, 문제가 발생합니다. VisualStudio에 내장되어 있는 new의 경울 8byte align으로 할당되므로 우리는 16byte align 으로 enw, delete를 새로 만들어서 사용가능하도록 보장해 주어야 합니다. (MSDN 에서도 새롭게 _aligned_malloc 과 _aligned_free를 이용하여 새로운 new, delete 할당자를 만들라고 설명되어 있습니다.)
즉, 'VisualStudio 에서 제공되는 기본 new, delete 명령어는 8byte 정렬을 사용하는데 XMMATRIX 변수의 경울 16byte 정렬을 사용하도록 명시하고 있으므로 HEAP 할당시에 컴파일러는 보장하지 않을것이니, 사용자 너가 알아서 처리해!!' 라는 말입니다.
만약, C4316을 해결하지 않게된다면?
CPU에서 SSE 명령어 연산을 처리할 때 정렬되는 데이터를 안전하게 보장받을 수 없습니다.
해결방법
new, delete를 _aligned_malloc, _aligned_free를 사용하여 재정의 하여 사용하면 됩니다.
AlignedAllocationPolicy.h
#pragma once
// warning C4316 처리용
template<size_t T>
class AlignedAllocationPolicy
{
public:
static void* operator new(size_t size)
{
return _aligned_malloc(size,t);
}
static void operator delete(void* memory)
{
_aligned_free(memory);
}
};
위와 같이 재정의 템플릿을 생성한 다음 아래와 같이 사용하면 됩니다.
#pragma once
class CameraClass : public AlignedAllocationPolicy<16>
{
public:
CameraClass();
CameraClass(const CameraClass& cameraClass);
~CameraClass();
void SetPosition(float x, float y, float z);
void SetRotation(float, float, float);
XMFLOAT3 GetPosition();
XMFLOAT3 GetRotation();
void Render();
void GetViewMatrix(XMMATRIX&);
private:
XMFLOAT3 m_position;
XMFLOAT3 m_rotation;
XMFLOAT3 m_viewMatrix;
};
'DirectX' 카테고리의 다른 글
5. 조명 (0) | 2022.11.21 |
---|---|
4. 텍스쳐 (0) | 2022.11.11 |
3. 버퍼, 쉐이더 및 HLSL (0) | 2022.10.10 |
2. DirectX 초기화 (0) | 2022.10.03 |
1. 프레임 워크 및 윈도우 (0) | 2022.10.03 |