[C언어/C++] 구조체, 클래스의 패딩 바이트에 대하여

구조체, 클래스의 크기와 패딩바이트

구조체나 클래스의 크기는 어떻게 결정될까요? 구조체나 클래스 내부에 선언된 변수들의 크기로 결정된다고 생각하실 수 있는데 실제로 크기를 확인해보면 대부분 내부의 선언된 변수의 크기들보다 더 큰 크기의 공간이 할당되어 있습니다. 바로 패딩 바이트 때문에 그렇습니다. 패딩 바이트란 클래스나 구조체에 패딩 바이트를 추가하여 CPU 접근을 더 용이하게 해 주는 것을 말합니다. 자칫 공간 낭비일 수도 있는 불필요한 패딩 공간을 확보하면서 메모리의 크기를 맞추는 이유는 캐시 hit율을 높이고 CPU의 연산 횟수를 줄이기 위해서입니다. 

 

패딩바이트 생성 예제

#include <stdio.h>

struct temp {
    int a; // 4byte
    int b; // 4byte
    char c; // 1byte
    char d; // 1byte
    double e; // 8byte
    short f; // 2byte
};

void main() {
    printf("구조체 temp의 크기 : %d\n", sizeof(temp));
}

위의 예제 파일을 실행시켜보면 구조체의 크기가 32byte가 나옵니다. 실질적으로 temp 구조체 안에 있는 변수는 int형 (4byte) 2개, char형(1byte) 2개, double형(8byte) 1개, short형(2byte) 1개로 총 선언되어있는 멤버 변수들의 크기는 (4+4+1+1+8+2)로 총 20byte임에도 실제 크기는 32가 나왔습니다.

실질적으로는 위와 같이 padding이 들어가 있어 총 32byte라는 크기가 나오게 되는 것입니다.

32비트 CPU는 한번에 4바이트. 64비트 CPU는 한번에 8바이트를 읽을 수 있습니다. 32비트 CPU를 예로 들면 위와 같이 읽게 되는데 패딩 바이트를 사용하지 않으면 위처럼 마지막 1byte가 남게 되어 연산을 두 번 처리하게 됩니다.

 

위의 상황을 방지하기 위해 패딩 바이트가 들어가게 됩니다. 위와 같이 패딩 바이트를 추가하여 한 번의 연산에 하나의 값이 들어가게 되고 메모리는 더 사용하나 CPU는 한 번의 동작만 하면 되기에 연산이 보다 빠르게 처리가 됩니다.

 

효율적인 공간 설계

#include <stdio.h>

struct temp {
    double e; // 8byte
    int a; // 4byte
    int b; // 4byte
    char c; // 1byte
    char d; // 1byte
    short f; // 2byte
};

void main() {

    printf("구조체 temp의 크기 : %d\n", sizeof(temp));
}

어떠한 상황에서든 메모리는 효율적으로 사용하는 것이 좋습니다. 별 차이 나지 않겠지 하며 대수롭게 여기기보다는 개발자라면 패딩 바이트는 최소한으로 생성되도록 유도하는 것이 필요합니다. char형은 1byte이기에 어디든지 붙을 수 있어 상관이 없지만 double형과 같은 큰 byte를 소모하는 자료형이라면 될 수 있으면 가장 위에 선언해주어 불필요한 메모리 낭비를 줄이는 것이 좋습니다.

 

double형 변수의 자리만 옮겼을 뿐인데 공간이 무려 8이나 줄어들었습니다. 

댓글(0)

Designed by JB FACTORY