구조체 패딩은 컴퓨터 메모리에서 데이터를 효율적으로 접근하기 위해 사용되는 개념이다. 컴퓨터 아키텍처 대부분은 특정 데이터 타입을 메모리의 정렬된 주소에서 읽고 쓰는 것을 선호한다. 예를 들어, 많은 시스템에서는 4바이트 정수(int)를 4바이트 경계에서 시작하는 메모리 주소에서 접근하는 것이 더 빠르다. 이러한 정렬 요구 사항을 충족시키기 위해 컴파일러는 구조체 내의 필드 사이에 "패딩" 바이트를 추가하여 메모리 접근 속도를 최적화한다.
⭐1. 구조체 패딩의 필요성
1.1.메모리 접근 속도 최적화: 데이터를 그들의 자연 정렬 경계에 맞춰 저장함으로써, CPU는 메모리에서 데이터를 더 빠르게 읽고 쓸 수 있다.
1.2.플랫폼 호환성: 다양한 플랫폼과 아키텍처에서 코드의 동작을 일관되게 유지한다.
⭐2. 패딩이 발생하는 원인
다음 구조체를 고려해본다:
typedef struct {
char a; // 1바이트
int b; // 4바이트
} Example;
char 타입의 a는 1바이트만 차지한다. 그러나 int 타입의 b는 4바이트 경계에 맞춰 정렬되어야 한다. 이 경우, a와 b 사이에 3바이트의 패딩이 삽입된다. 그러므로 총 1바이트 + 3바이트 (패딩) + 4바이트로 8byte로 메모리가 할당된다.
⭐3. 패딩 최소화
아래의 예제 코드는 세 가지 버전의 SensorData 구조체를 비교한다:
최적화되지 않은 버전, 수동으로 최적화된 버전, 그리고 컴파일러 지시문을 사용하여 최적화된 버전이다. 이를 통해 구조체의 크기가 어떻게 변하는지 확인할 수 있다.
3.1. 최적화되지 않은 구조체: 필드가 선언된 순서대로 배치된다. 이 경우, 컴파일러는 자동으로 패딩을 삽입할 수 있다.
3.2. 수동으로 최적화된 구조체: 데이터 타입의 크기에 따라 필드를 재배열하여 패딩을 최소화한다.
3.3. 지시문을 사용하여 최적화된 구조체 (__attribute__((packed))): 컴파일러가 어떠한 패딩도 추가하지 않도록 지시하여 구조체의 크기를 최소화한다.
#include <stdio.h>
// 최적화되지 않은 구조체
typedef struct {
char status; // 1 byte
int temperature; // 4 bytes
char config; // 1 byte
// Potential padding here
} UnoptimizedSensorData;
// 수동으로 최적화된 구조체
typedef struct {
int temperature; // 4 bytes
char status; // 1 byte
char config; // 1 byte
// Less or no padding compared to UnoptimizedSensorData
} OptimizedSensorData;
// 지시문을 사용하여 최적화된 구조체
typedef struct {
char status; // 1 byte
int temperature; // 4 bytes without padding due to directive
char config; // 1 byte
} __attribute__((packed)) PackedSensorData;
int main() {
printf("최적화되지 않은 구조체 크기: %zu 바이트\n", sizeof(UnoptimizedSensorData)); // 12byte
printf("수동으로 최적화된 구조체 크기: %zu 바이트\n", sizeof(OptimizedSensorData)); // 8byte
printf("지시문을 사용하여 최적화된 구조체 크기: %zu 바이트\n", sizeof(PackedSensorData)); // 6byte
return 0;
}
이 코드는 다음을 수행한다:
각 구조체의 메모리 크기를 sizeof 연산자를 사용하여 계산하고, 그 결과를 출력한다. 이를 통해 구조체의 메모리 사용량을 비교할 수 있다.
최적화되지 않은 버전에서는 int 타입 필드 사이에 있는 char 타입 필드로 인해 추가 패딩이 발생할 수 있다.
수동으로 최적화된 버전에서는 필드를 재배열하여 추가 패딩의 가능성을 줄인다.
지시문을 사용하여 최적화된 버전에서는 __attribute__((packed))를 사용하여 모든 패딩을 제거하고, 구조체의 크기를 가능한 최소로 만든다.
실행 결과는 컴파일러와 아키텍처에 따라 다를 수 있으나, 일반적으로 지시문을 사용하여 최적화된 구조체가 가장 작은 메모리 크기를 가지게 된다. 그러나, 비정렬 메모리 접근으로 인해 성능 저하나 플랫폼에 따른 문제가 발생할 수 있으므로, 사용 시 주의가 필요하다.
'Language > C언어' 카테고리의 다른 글
[C/C++ Tip] 7. 배열의 기초 (1) | 2024.09.04 |
---|---|
[C/C++ Tip] 6. UNION 공용체와 STRUCT 구조체로 패킷 만들기 (2) | 2024.09.04 |
[C/C++ Tip] 4. 구조체 활용: 효율적인 데이터 관리 (2) | 2024.09.02 |
[C/C++ Tip] 3. 코딩 규칙. 변수명 정하기 (0) | 2024.09.01 |
[C/C++ Tip] 2. #define의 목적 (0) | 2024.09.01 |