C4316 alignment error 해결

10
alignment error(C4316)는 무엇이며 어떻게 해결하나 warning C4316: 'A' : object allocated on the heap may not be aligned 16

description

C4316 alignment error 해결

Transcript of C4316 alignment error 해결

Page 1: C4316 alignment error 해결

alignment error(C4316)는 무엇이며 어떻게 해결하나

warning C4316: 'A' : object allocated on the heap may not be aligned 16

Page 2: C4316 alignment error 해결

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은 특정 크기에 맞춰 데이터를 정렬시키는 것

Page 3: C4316 alignment error 해결

그래서 우리 visual studio에서도 char double, int

로 13byte짜리 struct을 만들어도 알아서

이렇게 정렬을 해버린다.

참고로 데이터들 사이에 8byte를 맞추기 위해서

컴파일러가 알아서 넣어주는 부분을 padding이라

고 한다.

padding을 작게 하려면 struct을 만들 때, 크기가

작은 놈들부터 선언해두면 좋다.

Page 4: C4316 alignment error 해결

필요에 따라서는 정렬할 크기를 바꿔야 할 때가 있다.

우리가 직면한 문제는 바로 matrix16인데 이 놈은 내

부적으로 정렬사이즈를 바꿔주는 함수

_declspec(align(16))이란 놈을 이용해서 16byte로 정

렬되고 있다.

Page 5: C4316 alignment error 해결

그럼 MATRIX16은 왜 16BYTE 정렬을 하는가?!

우리가 선형대수에서 배운데로 행렬 연산을 하려면 행 열 별로 곱하고 더하고 지

지고 볶는 많은 연산들이 필요해 overhead가 크다.

근데 이러한 행렬 연산을 게임 등에서 많이 사용하므로 컴퓨터가 좋아지면서 이

런 행렬을 한 번에 처리할 수 있는 새운 명령어 집합이 추가되었다. (SSE라는 놈

으로 http://spy1233.tistory.com/47에서 누가 간단히 정리해두었으니 참고~)

이 SSE라는 놈이 16BYTE로 정렬된 데이터를 필요로 한다는 것!!

Page 6: C4316 alignment error 해결

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 );

Page 7: C4316 alignment error 해결

우리 프로젝트에서는 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 );

}

Page 8: C4316 alignment error 해결

http://stackoverflow.com/questions/20104815/warning-c4316-object-

allocated-on-the-heap-may-not-be-aligned-16

Page 9: C4316 alignment error 해결

No!!

malloc과 그의 친구들은 heap에 메모리를 할당할 때 8byte

만 보장해주기 때문에 16byte를 할당할 때 잘 될지 보장할 수

없어.

CPU에서 SSE 명령을 사용할 때 정렬되지 않은 데이터들이

문제가 될 수 있음

new랑 delete를 새로 만들어^^

_aligned_malloc(), _aligned_free() 쓰면됨

무시하면 어케됨?

원인이 뭐임?

어떻게 해결?

warning 4316이 뭔가요?

보장할 수 없을 만큼 많은 바이트가 할당되어 과도하게 정렬

된 struct에 대해 C4316이 발생 다음 장에 MSDN 문서 참고..

Page 10: C4316 alignment error 해결

보장할 수 없을 만큼 많은 바이트가 할당되어 과도하게 정렬된 struct에 대해 C4316

이 발생