반응형

[기본 용어 설명]

- 바이트 패딩: 

몇몇 컴파일러는 구조체의 필드를 메모리에 위치시킬때 중간에 빈공간없이 쭉 이어서 할당하는 경우도 있지만 대부분의 컴파일러는 성능향상을 위해 CPU가 접근하기 쉬운 위치에 필드를 배치하는데(OS나 컴파일러에 따라 4바이트단위 또는 8바이트 단위로 끊는작업을 함) 이를 "바이트 패딩"이라고 하며, 그러다보니 중간이 빈 공간이 들어가게 되는데 이 빈 공간을 "패딩비트"라 한다.  

 

* 바이트패딩을 사용했을때 왜 성능향상에 도움을 줄까? 그 해답은 아래 링크를 통해 확인바람

http://pangate.com/19

 

이러한 바이트 패딩 때문에 구조체 정의를 어떻게 하느냐에 따라 구조체의 크기가 달라진다. 아래 예제를 살펴보자.

 

예)







 

- 위에서 보는것 처럼 구조체 ST_TEST1, ST_TEST2의 멤버변수는 동일하다. 하지만 변수의 선언 순서에 따라 바이트패딩이 적용되서 사이즈가 다르게 된다. 

바이트 패딩 의해

ST_TEST1 은

[char c1 (1) | empty(1) | short s1(2)]   ||   [int i1(4)]                    = 총 8바이트

ST_TEST2 는

[char c1(1) | empty(3)]   ||   [int i1(4)]   ||   [short s1(2) | empty(2)] = 총 12바이트

 

* empty : 빈공간, 즉 패딩비트 [] : 4바이트씩 모아놓은것.

* 실제 ST_TEST1 정렬방법(char 뒤에 1바이트 패딩비트가 생기는지)을 확인하고 싶으면 디버깅 - 창 - 조사식에 각 구조체의 변수의 주소를 확인해보면 된다. 아래 스샷을 보면 c1과 s1 사이에 1바이트 빈공간이 존재한다.  

 

 

이러한 문제를 해결할수 있는 방법이 바로 #paragma pack 이다.  

 

사용 방법은 2가지다.

 

1. #pragma pack(1)  - #pragma pack(4)

1바이트 정렬 방식이 필요할때 필요한 구문에서

#pragma pack(1) 을 써주고 (2바이트 정렬이 필요하다면 #paragma pack(2))

사용이 끝난 시점에서 다시 #pragma pack(4) 를 통해 바이트 정렬 방식을 4바이트로 되돌려 놓는다.

 

※  

Q: 왜 굳이 1바이트 정렬 후 다시 4바이트 정렬로 되돌려야하는가??

A:  PC의 CPU에 따라 레지스터를 읽는 바이트 사이즈가 다른데 32비트 운영체제의 경우 4바이트씩 읽는다 . 이는 성능과 연관있다. (자세한 내용은 컴퓨터 구조 공부를... ) 따라서 필요시에만 정렬방법을 바꿨다가 다시 기존 바이트 정렬 방식으로 돌려 놓아야한다.

 

2. #pragma pack(push, 1)  - #paragma pack(pop)

- #pragma pack(push, 1) 을 통해 구조체 정렬방식을 가지고 있는 스택에 1바이트 정렬방식을 push 를 통해 입력하고 ( 이 선언 이후부터는 정렬방식이 1바이트 바뀜)  사용 후에 이전 정렬방식( 이전 방식이 꼭 4 라는 법은 없음)되돌릴때 pop을 통해 이전에 push를 통해 입력했던 정렬방법(1)을 없앤다. 이를 위해 #pragma pack(pop) 을 사용한다.

* push 와 pop 이 뭔지 생소하다면 스택(Stack)에 대해 공부할것.

 

사용 예)

 

- 스샷 화면 속 빨간 네모 속 ST_TEST2 사이즈를 보면 7로 변해있는것을 확인할수 있다.

#paragma pack 을 쓰기 전에는 12바이트.

 

★ 그렇다면 가장 중요한 포인트! 이 #pragma pack 어디다 쓰면 유용한 건데???

moon_and_james-11

- 네트워크를 통한 구조체 전송시 바이트 패딩은 중요하다!

 

예) 만약 A시스템(32비트) B시스템(64비트)라고 가정, A시스템에서 B시스템으로 아래와 같은 구조체 패킷을 보낸다고 하면

struct ST_TEST

{

char c1;

int i1;

};

B 시스템은 바이트 패딩에 의해 A시스템과는 달리 8바이트단위로 끊는다. 따라서 첫번째 c1값만 정상이고 나머지 값들은 이상한값이 되버린다.

따라서 A시스템, B시스템 모두 바이트 패딩을 없애야 이러한 문제를 없앨수 있는데 이 해결방법이 위에 설명했던 #paragma pack 이다.  



http://blog.naver.com/dkdldhekznal/220206729625

반응형

+ Recent posts