2. C4316 도대체 무엇인가!!
이를 위해서는 먼저 align에 대해 알아야 한다.
64bit컴퓨터에서 cpu가 한번에 처리할 수 있는 데이터 양은 64bit!!
결국 8byte씩 처리하는 게 제일 합리적.
(32bit에서는 4byte? align크기는 컴파일러 마다 다른 듯 하다.)
가령, 빨간 색 데이터를 읽어올 때,
http://www.songho.ca/misc/alignment/dataalign.html
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
얘는 한번 access에 가능하지만
얘는 두 번 데이터를 access해서 합쳐야 한다.
이러니 데이터들을 저장할 때 8byte크기에 맞춰두는 것이 성능 관점에서 유리할
수 밖에.. 이렇게 align은 특정 크기에 맞춰 데이터를 정렬시키는 것
3. 그래서 우리 visual studio에서도 char double, int
로 13byte짜리 struct을 만들어도 알아서
이렇게 정렬을 해버린다.
참고로 데이터들 사이에 8byte를 맞추기 위해서
컴파일러가 알아서 넣어주는 부분을 padding이라
고 한다.
padding을 작게 하려면 struct을 만들 때, 크기가
작은 놈들부터 선언해두면 좋다.
4. 필요에 따라서는 정렬할 크기를 바꿔야 할 때가 있다.
우리가 직면한 문제는 바로 matrix16인데 이 놈은 내
부적으로 정렬사이즈를 바꿔주는 함수
_declspec(align(16))이란 놈을 이용해서 16byte로 정
렬되고 있다.
5. 그럼 MATRIX16은 왜 16BYTE 정렬을 하는가?!
우리가 선형대수에서 배운데로 행렬 연산을 하려면 행 열 별로 곱하고 더하고 지
지고 볶는 많은 연산들이 필요해 overhead가 크다.
근데 이러한 행렬 연산을 게임 등에서 많이 사용하므로 컴퓨터가 좋아지면서 이
런 행렬을 한 번에 처리할 수 있는 새운 명령어 집합이 추가되었다. (SSE라는 놈
으로 http://spy1233.tistory.com/47에서 누가 간단히 정리해두었으니 참고~)
이 SSE라는 놈이 16BYTE로 정렬된 데이터를 필요로 한다는 것!!
6. 16BYTE 정렬된 데이터를 그냥 사용할 때는 문제가 없다.
문제는 HEAP영역에 할당할 때이다. vs 내장 NEW는 내부적으로 메모리를 할당
할 때 8byte allign을 사용해서 한다. 따라서 우리는 16byte align을 지원하는 new,
delete를 새로 만들거나 align되도록 보장해주어야 한다.
new 동작은 memory를 allocate하는 동작과
해당 객체의 생성자를 호출해주는 부분 두 가지로 나뉘어져 있다.
따라서 new할 때는 16byte 할당 후 생성자를 호출하고
m_pInstance = (T*)_aligned_malloc( sizeof( T ), 16 );
new (m_pInstance)T();
delete할 때는 역순으로 소멸자를 호출한 뒤 메모리를 free한다.
m_pInstance->~T();
_aligned_free( m_pInstance );
7. 우리 프로젝트에서는 object들이 smart_pointer를 사용하고 있으므로 shared_ptr
에 deleter로 등록시켜주면 기본 delete동작 대신에 위의 동작을 수행하게 된다.
void DDObject::DeleteAlignedClass( DDObject* object )
{
object->~DDObject();
_aligned_free( object );
}
void DDObject::AddChild( DDObject* object )
{
auto deleter = DeleteAlignedClass;
std::shared_ptr<DDObject> object_ptr( object, deleter );
object->SetParent( this );
m_ChildList.push_back( object_ptr );
}
9. No!!
malloc과 그의 친구들은 heap에 메모리를 할당할 때 8byte
만 보장해주기 때문에 16byte를 할당할 때 잘 될지 보장할 수
없어.
CPU에서 SSE 명령을 사용할 때 정렬되지 않은 데이터들이
문제가 될 수 있음
new랑 delete를 새로 만들어^^
_aligned_malloc(), _aligned_free() 쓰면됨
무시하면 어케됨?
원인이 뭐임?
어떻게 해결?
warning 4316이 뭔가요?
보장할 수 없을 만큼 많은 바이트가 할당되어 과도하게 정렬
된 struct에 대해 C4316이 발생 다음 장에 MSDN 문서 참고..
10. 보장할 수 없을 만큼 많은 바이트가 할당되어 과도하게 정렬된 struct에 대해 C4316
이 발생