간단한 c 구조체를 생각해 보겠습니다.
struct foo { const char * str; unsigned char flag; uint64_t len; };
이 코드가 64비트 시스템에서 실행되는 프로그램의 일부로 실행된다고 가정해 보겠습니다. sizeof(struct foo)의 결과는 어떻게 될까요?
구조체 크기와 최적화를 망쳐본 적이 없는 대부분의 사람들은 17이 되어야 한다고 추측할 것입니다...
... 하지만 24살이에요! 왜 그럴까요?
이러한 동작의 이유는 컴파일러가 속도를 위해 구조체 레이아웃을 최적화하고, 정렬된 메모리 액세스가 데이터에 액세스하는 가장 빠른 방법이라는 것이 현대 표준이기 때문입니다.
즉, 필드 및 CPU 유형에 따라 데이터가 일부 정렬을 가지며 정렬이 준수되도록(또는 필드 주소 % 필드 정렬 == 0) 배치됩니다.
이전 예의 경우 포인터와 64비트 필드는 64비트 시스템에서 8B로 정렬됩니다. 즉, 구조체의 모든 항목이 정렬되는 레이아웃을 강제로 적용하기 위해 컴파일러는 일부를 생성합니다. 플래그와 len 필드 사이의 패딩:
이제 이전과 동일한 시스템에서 이와 같은 구조체가 정의된 또 다른 예를 고려해 보겠습니다.
struct bar { const char * str; short s1; int i1 short s2; int i2; };
크기를 어떻게 계산하나요?
세 가지 규칙이 있습니다.
64비트 시스템의 기본 유형 정렬 및 크기에 대한 빠른 요약:
type | size | alignment |
---|---|---|
char | 1 | 1 |
short | 2 | 2 |
int | 4 | 4 |
long | 8 | 8 |
float | 4 | 4 |
double | 8 | 8 |
pointers | 8 | 8 |
다음 사항도 기억하세요.
그리고 매우 유용한 sizeof 및 _Alignof 연산자를 사용하여 사용자 정의 유형에 대한 이 정보를 얻을 수 있습니다. _Alignof는 C11부터 사용할 수 있으며 C23부터 alignof라고 합니다. C 11 이후로 항상 C에서 이해하는 것과는 alignof였습니다.
이 주제에 대한 자세한 내용은 The Lost Art of Structure Packing에서 많은 연습과 실무 경험을 통해 제가 아는 거의 모든 것을 배웠습니다.
이 주제는 직장에서 자주 언급되는 내용으로, 대기열 등에서 막대한 양의 데이터를 지속적으로 전송할 때 여기저기서 바이트를 절약하는 것이 매우 중요합니다.
내 삶을 더 쉽게 만들기 위해 소스 파일이나 코드 조각을 참조하여 입력으로 전달하는 유형에 대한 통계를 생성하는 stropt (구조체 최적화 프로그램).
GitHub의 Abathargh/stropt빌드 및 설치
struct foo { const char * str; unsigned char flag; uint64_t len; };os/archs 조합 목록에 대해 이미 컴파일된 바이너리도 github 릴리스 페이지에서 제공됩니다.
스트롭 바이너리
도구를 사용하여
struct bar { const char * str; short s1; int i1 short s2; int i2; };
git clone https://github.com/Abathargh/stropt go build // or, if you want to install this directly go install github.com/Abathargh/stropt
다음은 무엇입니까
이 글은 나 자신을 위해 작성되었지만 공개적으로 공유하게 되어 기쁩니다. 브라우저에서 직접 더 쉽게 사용할 수 있도록 이것을 웹앱으로 만들고 싶습니다. 아마도 이것이 제가 작업할 다음 작업일 것입니다!
위 내용은 C 구조체 레이아웃 최적화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!