[Server Programming/cpp] Packet에서 #pragma pack()을 사용하는 이유
#pragma pack()?
Packet.h
#pragma pack(push, 1)
struct PktHeader {
short TotalSize;
short Id;
unsigned char Reserve;
};
#pragma pack()란 구조체의 메모리 정렬 방식(메모리 패딩)을 변경하는 데 사용되는 전처리기 지시어다.
기본적으로 C++에서 구조체를 정의할 때, 컴파일러는 성능 최적화를 위해 각 멤버 변수의 메모리를 특정 크기로 정렬하여 패딩을 넣는데,
이렇게 하면 구조체의 크기가 커질 수 있기 때문에, #pragma pack(push,1)을 사용하면 멤버 변수들이 1바이트 단위로 연속적으로 배치되어, 패딩 없이 메모리를 사용할 수 있다.
push, pop
- #pragma pack(push,n)
- #pragma pack(pop)
push시 선언된 스코프 내의 모든 struct 저장 시에 컴파일러가 패딩을 최적화해서 저장하도록 한다.
pop을 선언하면 push 설정을 취소하고 struct 저장을 기본값으로 돌려 다시 패딩 최적화를 하도록 한다.
struct의 저장 방식
구조체의 각 멤버는 메모리의 연속된 공간에 저장되는데, 컴파일러는 성능을 높이기 위해 **패딩(padding)**을 추가해 멤버들을 정렬하는 경우가 많다.
메모리 패딩 은 멤버 변수를 최적의 메모리 경계에 맞춰 배치하기 위해 추가되는 빈 공간
struct MyStruct {
char a;
int b;
char c;
};
| 1바이트 | 3바이트 패딩 | 4바이트 | 1바이트 | 3바이트 패딩 |
|---|---|---|---|---|
| a | (패딩) | b | c | (패딩) |
언제 씀?
- 메모리 크기 최적화를 위해 네트워크 전송시 메모리 효율성과 전송 속도이 중요한데, 패킷에 패딩까지 포함되는건 낭비임.
장단점
장점 메모리 최적화
단점
- 비정렬된 데이터에 cpu가 접근하면 더 많이 접근을 시도하고 성능 저하가 일어남
- 캐시 메모리의 캐시 효율이 낮아진다. 만약 잘 정렬된 기존의 구조체라면 금방 갖다 쓸것이다.