Memory Alignment

2025. 12. 30.
게시일
Dec 30, 2025

기초 지식

 

Memory Align

CPU(엄밀히는 CPU 속의 MMU)는 메모리 주소를 Word 단위로 쪼갠다.
따라서 시작 주소는 Word의 크기(바이트)의 배수여야 한다.
예를 들어 int형이라면 4의 배수여야 하고, double형이라면 8의 배수여야 한다. 그러니 int형 데이터의 4 바이트가 0x0007~0x000A까지 저장 되어 있다면 이는 정렬되지 않은 것이다. (시작 주소 7이 4의 배수가 아니기 때문)
따라서 64bit CPU의 Word의 크기인 8바이트 단위로 메모리를 정렬해야 함.

함정 : 요즘엔 16바이트 정렬을 더 많이함

SIMD 명령어의 등장으로, SIMD는 16바이트 단위로 메모리에 접근한다.
 
 
왜 이렇게 접근을 하느냐? CPU의 레지스터 부터 MMU의 주소까지, Word 단위로 가져오는 것이 고정되어있기 때문이다. (즉, 그냥 CPU가 그렇게 생겨먹어서 그런 것임)
최신 x86-64 아키텍처의 경우 정렬되지 않은 접근이 성능 저하를 불러오지 않는다는 글도 찾을 수 있었다.

Object Padding (struct padding)

struct도 memory alignment를 지켜야 한다. 기본적으로 컴파일러는 object뿐만 아니라 모든 종류의 변수 (stack 변수와 배열, heap에 동적할당된 변수 등등)에 메모리 정렬을 적용한다.
 
  1. 각 멤버 변수는 정렬된 위치에 놓여야 한다.
위의 Memory Align과 동일한 맥락이다.
  1. Object의 총 크기는 최고 크기의 멤버 변수의 배수만큼 되어야 한다.
구조체 이후에도 계속해서 메모리가 정렬되도록 하려면 이 규칙이 필요하다.
struct foo { int a; char b; } foo[100];
foo[0]은 당연히 정렬되어있다. 그러나 foo[1] 부터는 정렬이 틀어진다.

사용자 정의 정렬

alignas(32) int i; // 32비트 boundary에 시작주소가 오도록 align
alignas() 키워드를 사용하면 컴파일러에게 사용자 정의로 정렬을 수행하도록 지시할 수 있다. 물론 이 명령어를 사용할 때는 매우 주의해야 하는데, 정렬이 잘못된 채로 접근한다면 일부 CPU에서는 fault를 발생시킬 수도 있기 때문이다.

Cache Line Alignment

현대 CPU는 대체로 L1 캐시라인의 크기가 64B인데, 이 64B에 맞추는 메모리 정렬도 있다. 이를 cache Line Alignment라고 한다. 자세한 것은 아래 글 참조.
[메모리] 2. 캐시 메모리
 
 
제목: Memory Alignment작성일: 2025. 12. 30.