ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 64비트 시스템에서 메모리 정렬 경계에 대해
    개발/C·C++ 2024. 10. 11. 14:52

    64bit 프로세서의 64bit 모드에서 메모리 동적할당을 하면 주소 값이 16바이트 정렬이 기본 값인 것 같다.

    struct PureNode
    {
    	int a;
    	int b;
    	int c;
    };
    
    
    int main()
    {	
    	constexpr int ALIGN = 16;
    	for (int i = 0; i < 10000; ++i)
    	{
    		uintptr_t node1 = reinterpret_cast<uintptr_t>(new PureNode());
    		uintptr_t node2 = reinterpret_cast<uintptr_t>(new PureNode());
    		uintptr_t node3 = reinterpret_cast<uintptr_t>(new PureNode());
    		uintptr_t node4 = reinterpret_cast<uintptr_t>(new PureNode());
    		uintptr_t node5 = reinterpret_cast<uintptr_t>(new PureNode());
    
    		ASSERT_CRASH(node1 % ALIGN == 0);
    		ASSERT_CRASH(node2 % ALIGN == 0);
    		ASSERT_CRASH(node3 % ALIGN == 0);
    		ASSERT_CRASH(node4 % ALIGN == 0);
    		ASSERT_CRASH(node5 % ALIGN == 0);
    
    		delete reinterpret_cast<PureNode*>(node1);
    		delete reinterpret_cast<PureNode*>(node2);
    		delete reinterpret_cast<PureNode*>(node3);
    		delete reinterpret_cast<PureNode*>(node4);
    		delete reinterpret_cast<PureNode*>(node5);
    	}
    }

     

    ASSERT_CRASH 매크로 함수는 표현식이 거짓일 경우 크래시를 내도록 되어 있다. 기본으로 제공되는 _ASSERT 매크로 함수는 디버그 모드에서만 동작하기 때문에 테스트 할 때는 디버그/릴리즈 모든 환경에서 검사하는 게 목적이었으므로 별도로 만들었다.

     

    32bit 모드로 설정하니 8바이트가 기본 정렬인 것 같다.

     

    기본값이 있다고 해도 실제 개발할 때는 가독성과 확실함을 보장받기 위해 __declspec(align(x))를 써주도록 하자. 특히 MS에서 제공하는 SLIST 시리즈를 사용할 때는 메모리를 16바이트 경계에 놓는 것이 필수다.

    __declspec(align(16))
    struct PureNode
    {
    	int a;
    	int b;
    	int c;
    };

    https://learn.microsoft.com/ko-kr/windows-hardware/drivers/kernel/singly-and-doubly-linked-lists#sequenced-singly-linked-lists

     

    참고로 구조체를 __declspec(align(16))로 설정하고 32비트 모드에서 동적으로 메모리를 할당하면 비주얼 스튜디오 2022에서는 컴파일 단계에서 다음과 같은 경고를 내준다.

     

    댓글

Designed by Tistory.