programming2008. 4. 30. 15:41

1, 바이트 정렬(Byte Alignment) 왜 해야 하는가 ?

현재 일반적으로 많이 사용하는 32bit 체계를 예를들면, CPU 가 메모리에서 데이타를 가지고 올때
32bit 즉 4byte 의 데이타를 가지고 와서 처리를 한다. 이 얘기는 CPU 가 메모리의 주소를 4byte 단위로
쪼개서 접근을 한다는 말과 같겠다. 

말로 하면 머리에 잘 안들어온다. 예들 들어보도록 하자.

int n; 이라는 변수가 있다.
이변수의 주소는 0x1000 ~ 0x1004 이다. 왜냐 4byte 변수니까 4byte 를 차지하고 있겠지.
이러면 cpu 에서 메모리 0x1000 ~ 0x1004 의 조소를 한번에 받아 처리 할수가 있다.
CPU 는 32bit 씩 처리 되니까.
이러면 아무런 문제가 없다. 그런데 만일 int n;. 의 변수가 0x1001 ~ 0x1005 의 주소에
존재 한다고 생각해 보라.
그러면 CPU 는 메모리의 0x1000 ~ 0x1004, 0x1005 ~ 0x1008 의 주소를 받아서 처리해야
int n; 을 처리할 수 있는것이다.

그러면 쓰잘데기 없이 두번의 일을 하는 결과가 됐다. 그래서 바이트를 정렬해서 효율을 높이자는 것이다.

2, 그럼 실제 바이트 정렬(Byte Alignment) 을 어떻게 설정하나 ?

VC++ 설정에 보면 기본적으로 바이트 정렬해야 하는 byte 가 설정이 되어있다.
다른 컴파일러는 잘 모르것다. 있긴 있겠지 ㅡㅡ

사용자 삽입 이미지

[VC++ 71 설정화면]

이렇게 말로만 해서는 감이 안온다. 직접 코드를 보고 비교해 보장.

사용자 삽입 이미지














이와 같은 코드를 높고 설정값을 변경 해보자. 결과는 다음과 같다.

설정값 ==> nsize 값
1byte ==> 5 (ch, n, n, n, n)
2byte ==> 6 (ch0, nn, nn)
4byte ==> 8 (ch000, nnnn)
8byte ==> 8 (chnnnn000)

% ch: char 변수, n: int 변수, 0: byte padding

3, 컴파일러 바이트 패딩(Compiler Byte Padding) 은 무엇인가 ?

위의 예에서 STTEST 구조체가 실제 5byte 이라도 구조체 멤버 설정이 2byte 이면 6byte 로 나온다.
어떻게 처리되는 것일까 ?

2byte 단위로 정렬하기 때문에 하나의 단위를 2byte 라고 생각해 보자. 그리고 구조체 내의 변수를 넣어보자
처음 char 을 2byte 중 첫번째 바이트에 넣고 다음 int 를 넣으려고 했는데, 4byte 중 1byte 밖에 넣을수가
없다. 그래서 컴파일러는 2byte 정렬제한을 위반하지 않도록 바이트 패팅을 추가하여 char 를 2byte처럼
처리하고 다음 공간부터 int 를 저장한다.


4, 바이트 정렬을 코드에서 처리하기

바이트 정렬 구간을 소스에서 정의 하려면 "#pragma pack" 을 사용한다.

#pragma pack(1)
typedef struct Test
{
 char ch;
 int n;
}STTEST;
#pragma pack()

이렇게 사용하면 1byte 로 정렬하게 된다.
%참고로 "pragma" 키워드는 컴파일러에게 어떻게 처리하라고 명려하는 컴파일러 지시자 이다.

추가로 정렬을 Stack 를 이용할수도 있다.

#pragma pack(push, 1)
typedef struct Test
{
 char ch;
 int n;
}STTEST;
#pragma pack(pop)

요런식이 되겠다.

% 1,2,4,8,16 이외의 값을 설정하면 무시되고 컴파일러 옵션에 설정된 값으로 사용된다.
Posted by 상현달