구조체는 서로 다른 타입의 변수들을 묶어서 새로운 자료형으로 정의 하는 것입니다.
구조체에는 변수, 배열, 포인터,다른 구조체를 포함 할 수 있습니다.
Padding Bit
구조체의 크기는 구조체 안의 변수들을 합한 결과가 아니다.
다음의 코드를 보자.
struct st
{
int a;
char b;
short c;
char d;
int e;
}
int형 2개 8byte, char형 2개 2byte, short형 1개 2byte,총 11byte 이다.
하지만 sizeof 연산자를 통해크기를 출력하면 16byte가 나온다.
이것은 cpu 가 성능 저하를 막기 위해 넣어준 Padding Bit 때문이다.
32 bit cpu 가 데이터를 효율적으로 읽어 들이려면 32 bit 로 읽어야 한다.
그 이하면 필요없는 부분을 읽지 않는 작업을,
그 이상을 읽으면 32bit를 추가하고 나머지를 읽지 않는 작업을 해야한다.
이 과정에서 성능 저하가 일어난다.
그래서 구조체 변수를 읽어 올 때는 컴파일러가 성능 저하를 막기 위해 Padding bit 라는 것을 자동 추가 해준다. ( Padding bit 를 추가해주지 않는 컴파일러도 있다.)
Padding bit 가 추가되는 모습은 아래와 같습니다. (파란색 부분이 Padding bit 입니다.)
40
|
41
|
42
|
43
|
44
|
45
|
46
|
47
|
48
|
49
|
4A
|
4B
|
4C
|
4D
|
4E
|
4F
|
a
|
b
|
c
|
d
|
e
| |||||||||||
4byte
|
4byte
|
4byte
|
4byte
|
Padding bit 만큼 메모리를 낭비 되지만
32 bit 단위로 데이터를 읽어오면 되어 속도는 빨라진다.
하지만 이 프로그램이 통신에 쓰인다면 치명적인 문제점을 안게 된다.
또 한 #pragma pack(1) 이라고 선언해주면 선언 이후의 코드들을 전부 1byte 단위로 데이터를 읽기 때문에 엄청난 성능저하를 가져오게 된다.
이러한 성능 저하를 막기 위해 우리가 1byte 씩 읽어오기를 원하는 코드 전에서 #pragma pack(1)을 선언해주고 그 코드의 끝 부분에 다시 #pragma pack(4) 로 선언해주면 된다. 위의 코드에 적용해보면 다음과 같게 됩니다.
#include <stdio.h> |
하지만 이처럼 수정해주면 32 bit cpu에서는 괜찮지만 8 bit 나 16bit 또는 64 bit cpu 에서 다시 문제가 야기됩니다.
이때는 다음과 같이 해주면 됩니다.
#include <stdio.h>
#pragma pack(push, 1) //1byte 단위로 정렬 방식을 바꾸고 기존정렬방식을 스택에 저장합니다.
#pragma pack(pop) //스택에 저장한 정렬방식으로 다시 돌립니다. pack 지시자는 이 후 부터 선언되는 구조체의 정렬 방식을 지정하는 것입니다. 1은 컴파일러가 저장된 메모리에 데이터를 정렬하는 방법을 결정하는 byte의 크기입니다.
|
댓글 없음:
댓글 쓰기