18.2.2.3 패딩 제거에 따른 캐시 라인(Cache Line) 비정렬(Unaligned) 접근 페널티와 최적화 배치 기법
18.2.2.2절에서 다룬 __packed__ 지시어는 구조체 내부의 패딩(Padding)을 완전히 소멸시켜주지만, 치명적인 대가를 지불해야 한다. 변수들이 앞뒤 가리지 않고 밀착됨으로써, “비정렬 메모리 접근(Unaligned Memory Access)” 이라는 하드웨어 레벨의 페널티를 맞게 되는 것이다.
1. 비정렬 접근 페널티의 파급력
현대의 ARM 버스(Bus) 아키텍처나 L1 데이터 캐시(Cache) 모델에서, 64비트(8바이트) 크기의 double 변수는 주소가 8의 배수(0, 8, 16…)인 곳에 위치할 때 가장 빠르게 읽힌다. 이를 “자연 정렬(Natural Alignment)“이라 부른다.
만약 __packed__에 의해 1바이트짜리 bool 변수 바로 뒤에 빈 공간 없이 8바이트짜리 double 변수가 주소 1부터 위치하게 되었다고 가정하자. CPU가 이 8바이트를 읽기 위해서는 다음과 같은 부하가 발생한다.
- 주소
0부터 시작하는 첫 번째 캐시 라인(블록)을 읽어 들임. - 주소
8부터 시작하는 두 번째 캐시 라인(블록)을 연달아 읽어 들임. - 두 블록에서 필요한 비트(Bit)들만 교묘하게 잘라내어(Masking) 레지스터 상에서 하나로 이어 붙임(Shifting).
이 과정은 자연 정렬된 데이터를 읽을 때보다 최소 2~3배 이상의 클럭 사이클(Clock Cycle)을 낭비하게 만들며, 스위칭이 잦은 비행 제어 루프에서는 무시할 수 없는 전력 소모와 실행 시간(WCET) 증가로 직결된다.
2. PX4의 해법: 데이터 크기 내림차순 정렬(Sorting) 알고리즘
이 딜레마를 해결하기 위해 PX4 개발진은 파이썬 자동 생성 스크립트(px4_generate_messages.py)의 추상 구문 트리(AST) 파싱 단계에 극단적이고도 영리한 규칙 하나를 추가했다.
“개발자가 .msg 텍스트 파일에 변수를 어떤 순서로 적어 놓든 상관없이, C++ 구조체를 생성할 때는 무조건 데이터 타입의 크기(Byte Size)가 가장 큰 것부터 내림차순(Descending Order)으로 강제 정렬하여 배치한다.”
예를 들어 개발자가 다음과 같이 비효율적인 순서로 .msg를 작성했다고 치자.
uint8 system_id # 1 byte
float64 lat # 8 bytes
uint32 error_count # 4 bytes
파이썬 스크립트는 이 필드들을 크기순으로 재배치하여 msg.h.jinja 템플릿에 밀어 넣는다. 결과적으로 탄생하는 C++ 구조체의 메모리 레이아웃은 다음과 같이 바뀐다.
struct __EXPORT example_topic_s {
double lat; // 8 bytes (주소 0부터 시작, 8의 배수 정렬 완벽)
uint32_t error_count; // 4 bytes (주소 8부터 시작, 4의 배수 정렬 완벽)
uint8_t system_id; // 1 byte (주소 12부터 시작, 정렬 제약 없음)
} __attribute__((__packed__));
3. 성배의 완성: 완벽한 패킹과 완벽한 정렬의 공존
가장 덩치가 큰 8바이트(uint64_t, double) 데이터들이 구조체의 맨 앞자리를 선점하므로 무조건 자연 정렬 주소를 획득한다. 그 뒤를 이어 4바이트, 2바이트 변수들이 차례대로 빈 공간을 채우고, 마지막 찌꺼기 공간에 1바이트짜리 열거형이나 부울(Bool) 변수들이 레고 블록처럼 빈틈없이 끼워 맞춰진다.
이 내림차순 정렬 기법을 적용하면, 컴파일러에게 __packed__ 지시어를 통해 “패딩을 절대 넣지 마라“라고 협박함과 동시에, CPU 하드웨어에게는 “모든 변수가 우연히도 정렬 규칙에 완벽하게 들어맞는다“고 속이는 효과를 거둘 수 있다.
이로써 PX4-Autopilot은 “제로 패딩으로 플랫폼 간 제로-카피 호환성을 확보” 하면서도, “비정렬 캐시 페널티를 0%로 소멸” 시키는 두 마리 토끼를 완벽하게 잡아내는 쾌거를 이루게 방증한다. 이는 로보틱스 미들웨어 세계에서 그 유례를 찾기 힘든 고도로 세련된 시스템 엔지니어링의 정수라 할 것이다.