[1. 개요]
구조체 작성 시, 메모리 접근 및 구조체 크기 개선을 위한 byte align 관련 하여 정리한다.
[2. 예제]
#include <iostream>
struct A {
char a; // 1byte
int b; // 5byte
char c[2]; // 7byte
};
struct B {
char a; // 1byte
int b; // 5byte
char c; // 6byte
};
struct C {
char a; // 1byte
char c; // 2byte
int b; // 6byte
};
struct AA {
char a; // 1byte
char c[2]; // 3byte
int b; // 7byte
};
int main()
{
std::cout << sizeof(A) << std::endl;
// output is "12"
std::cout << sizeof(B) << std::endl;
// output is "12"
std::cout << sizeof(C) << std::endl;
// output is "8"
std::cout << sizeof(AA) << std::endl;
// output is "8"
return 0;
}
구조체 안에서 변수 하나는 4byte 단위로 할당되려고 한다.
struct A 에서
- char a 는 1byte 가 할당 된다.
- int b 는 4byte 를 할당 받는데, char a 뒤에 이어서 연속으로 할당 될 수 없다.
- 그래서 char a 를 위해서 4byte 공간을 할당하지만, 그 중 1byte 만 사용하는 것이다. (3byte 가 padding 됨)
그래서, 같은 멤버 구성이지만, struct B 와 struct C 의 크기가 다른 것이다.
[3. #pragma pack]
의도한만큼의 공간을 사용하려면, #pragma pack 을 이용하여 강제할 수 있다.
#include <iostream>
#pragma pack(push, 1)
// #pragma pack(push, 2)
// #pragma pack(push, 4)
// #pragma pack(push, 8)
// #pragma pack(push, 16)
struct A {
char a; // 1byte
int b; // 5byte
char c[2]; // 7byte
};
struct B {
char a; // 1byte
int b; // 5byte
char c; // 6byte
};
struct C {
char a; // 1byte
char c; // 2byte
int b; // 6byte
};
struct AA {
char a; // 1byte
char c[2]; // 3byte
int b; // 7byte
};
#pragma pack(pop)
int main()
{
std::cout << sizeof(A) << std::endl;
std::cout << sizeof(B) << std::endl;
std::cout << sizeof(C) << std::endl;
std::cout << sizeof(AA) << std::endl;
return 0;
}
#pragma pack(push, 1)
- 현재 메모리 정렬 방식을 스택에 푸쉬하고, 1byte 단위로 정렬한다.
#prgma pack(pop)
- 이전에 푸쉬한 메모리 정렬 방식을 복원한다.
구조체 크기를 줄여서, 전체 메모리 사용량을 줄일 순 있으나,
경우에 따라서는 메모리 접근 상 성능에 영향을 줄 수 있다.
- 메모리가 정렬되지 않으면 CPU는 메모리 접근 시 추가적인 작업을 해야 할 수 있으며, 이로 인해 성능이 저하될 수 있다.
- 예를 들어, 4바이트 크기의 데이터가 4바이트 경계가 아닌 곳에 배치되면 CPU는 두 번의 메모리 접근을 해야 할 수도 있다.
- 특정 아키텍처에서는 정렬되지 않은 데이터에 접근하려고 할 때 segmentation fault 가 발생 할 수 있다.
[4. 결론]
전체 메모리 사용량과 성능 사이에 tradeoff 를 고려하여 구조체를 작성하되,
가급적 4바이트 단위로 align 되는 방향으로 작성하는 것이 좋다.
특히, char 나 short 자료형 사용 시 주의하도록..
'분류대기' 카테고리의 다른 글
[리눅스] goto 사용 시 컴파일 (0) | 2025.01.14 |
---|---|
swagger-editor 설치 (0) | 2024.06.12 |
CUDA 설치하기, [윈도우, 리눅스] (0) | 2024.05.14 |
[내용 채워야 됨] CUDA 사용해보기 (0) | 2024.02.22 |
[좀 더 작성, 콜 스택 부분] Windows, c++, CallStack (0) | 2023.12.20 |