본문 바로가기

Cpp

바이트 패딩

바이트 패딩은 메모리 정렬 요구사항을 충족시키기 위해 구조체나 클래스의 멤버 사이에 추가적인 바이트가 삽입되는 현상이다.

 

데이터의 효율적인 접근을 도와주는 역할을 하기 때문에 접근에 대해서 성능 최적화 역할을 한다.

 

메모리 정렬이란?

CPU는 특정 바이트가지의 데이터를 읽고 쓰는 것이 효율적이다.

만약 4바이트 정렬이라면 필요한 데이터 타입은 메모리에서 4의 배수 주소에서 시작해야 최적의 성능을 제공한다.

 

정렬되지 않은 주소의 데이터를 읽고 쓰면 CPU가 추가 작업을 해야하는 단점이 생긴다.

 

바이트 패딩의 상황

구조체 또는 클래스에서 멤버 변수를 나란히 배치할 때, 각 변수는 자신의 데이터 정렬 요구사항에 맞게 배치되야 한다.

이때, 정렬을 맞추기 위한 패딩 바이트가 삽입된다.

 

class WhatIsPadding
{
	char a;
    char b;
	char c;
    char d;
};

 

  • 위의 클래스는 모든 멤버가 1바이트 크기이기 때문에 메모리 정렬 요구사항을 충족한다.

따라서 패딩 현상이 일어나지 않는다

 

class WhatIsPadding
{
	char a;
    int b;
    char c;	
};

 

  • a 가 1바이트
  • b 가 4바이트, 4바이트 정렬이 필요해진다.
  • c 가 1바이트

따라서 a 와 b , b 와 c 사이에 패딩 바이트가 생성된다.

 

이때 int b 를 기준으로 하므로 패딩 바이트는 각각 3바이트 씩 생성되어 12바이트 크기의 클래스가 된다.

 

 

이때 클래스나 구조체의 크기 계산은 규칙이 있다.

  • 각 멤버 변수는 자신의 정렬 요구사항에 맞게 배치된다.
  • 구조체의 전체 크기는 가장 큰 데이터 타입의 크기로 정렬된다.

 

struct WhatIsPadding
{
	char a;
    double b;
	int c;
}

 

  • a 1바이트
  • b 8바이트 정렬
  • c 4바이트 정렬
  • 총 크기는 b 변수의 8바이트를 맞추기 위해서 24바이트가 된다.

이러한 패딩을 최소화 하기 위해서 다음과 같이 선언 가능하다.

struct WhatIsPadding
{
	double a;
	int b;
   	char c;    
};

 

 

  • a 8바이트로 정렬
  • b 4바이트
  • c 1바이트 인데 8바이트 정렬 되어야하기 때문에
  • b + c 인 5바이트에서 3바이트를 더한 16바이트로 패딩을 최소화한다.

 

 

패딩을 제거하는 방법도 있다

#pragma pack(push, 1)
struct WhatIsPadding
{
	char a;
	int b;
	char c;
}

 

  • #pragma pack(push, 1) 는 패딩을 제거하고 모든 멤버를 1바이트 정렬한다는 뜻이다.
  • 따라서 결과는 6바이트가 나온다.
  • 다만, 이는 패딩을 제거하기에 CPU 에서 데이터 접근에서 추가 작업이 수행되어 성능이 떨어지거나 아예 호환이 안되는 문제가 생길 수 있다.

 

offsetof 를 이용해서 해당 구조체와 클래스의 시작 위치를 알 수 있다.

#include <iostream>
#include <cstddef> // offsetof

struct Example {
    char a;
    double b;
    int c;
};

int main() {
    std::cout << "Size of struct: " << sizeof(Example) << '\n';
    std::cout << "Offset of a: " << offsetof(Example, a) << '\n';
    std::cout << "Offset of b: " << offsetof(Example, b) << '\n';
    std::cout << "Offset of c: " << offsetof(Example, c) << '\n';
    return 0;
}

 

  • 출력 값이
  • 전체 24 바이트
  • a 의 시작 위치 0
  • b 의 시작 위치 8
  • c 의 시작 위치 16이 나온다.

 

 

 

 

 

'Cpp' 카테고리의 다른 글

#define 대신 const, enum, inline 을 생각 할 것  (2) 2024.12.14
C++의 하위 언어  (0) 2024.12.14
RAII란?  (0) 2024.11.02
해시 테이블  (0) 2024.05.27
객체지향의 4대 특성  (0) 2024.05.27