2012-04-12 3 views
3

64 비트 Linux 컴퓨터에 다음 구조체가 있습니다.64 비트 컴퓨터에서 구조체 정렬

struct __wait_queue_head { 
      spinlock_t lock; 
      struct list_head task_list; 
    }; 

where 

typedef struct { 
      raw_spinlock_t raw_lock; 
    } spinlock_t; 

and 

struct list_head { 
      struct list_head *next, *prev; 
    }; 

raw_spinlock_t is defined as: 

typedef struct { 
      volatile unsigned int slock; 
    } raw_spinlock_t; 

는 지금은 LP64 표준 다음 64 비트 리눅스 시스템에서 구조체 __wait_queue_head의 정렬을 이해하고 싶다. 내가 아는 바로는이 구조체의 첫 번째 필드 즉,

spinlock_t lock 

64 비트 시스템에서 4 바이트를 차지 부호 INT는이 구조체는 4 바이트 정렬 된 어드레스에서 시작해야한다. 그러나, 나는 그것이 실제 시스템에서는 그렇지 않다는 것을 알았다. 대신 struct는 8 바이트 정렬 주소에서 시작하지만 첫 번째 필드의 정렬 요구 사항은 4 바이트 정렬 주소로 충족됩니다. 기본적으로 구조체의 정렬을 제어하는 ​​것은 무엇입니까? 구조체 내의 필드에 대한 패딩 개념에 대해서는 분명합니다. 구조체 자체의 정렬 요구 사항은 혼란 스럽습니다.

+0

내가 맞으면 컴파일러가 각 필드를 성능 향상을 위해 8 바이트 정렬에 배치하겠습니까? 레지스터는 64b이므로 한 번에로드 될 수 있습니다. – fduff

+0

모든 필드가 8 바이트로 정렬되는 것은 아닙니다. 부호없는 short와 같은 데이터 유형은 2 바이트 정렬되고 부호없는 int는 4 바이트 정렬입니다. struct 외부의 변수의 경우 변수는 'sizeof (variable)'바이트 정렬 주소에서 정렬되어야합니다. – gjain

답변

6

구조체 정렬 요구 사항은 해당 멤버 중 가장 큰 정렬 요구 사항입니다. 이 경우 struct list_head에는 포인터가 포함되므로 struct list_head의 정렬은 8 바이트입니다. 그리고 struct __wait_queue_head에는 struct list_head이 포함되어 있기 때문에 정렬도 8 바이트입니다. 구조체의 정렬 요구 사항이 느슨하면 구조체 채우기가 멤버를 올바르게 정렬 할 수 없기 때문에 필요합니다.

+0

구조체 패딩을 사용하여 구조체의 모든 데이터 멤버를 올바르게 정렬하는 방법에 대한 예제를 제공 할 수 있습니까? IMO, 패딩은 항상 데이터 멤버를 올바르게 정렬하기에 충분합니다. – gjain

+1

@ Gaurav 8 바이트 멤버가 뒤에 오는 4 바이트 멤버가있는 구조체를 상상해보십시오. 패딩 규칙은 멤버간에 4 바이트의 패딩을 추가합니다. 구조체가 8 바이트로 정렬되면 두 멤버 모두 8 바이트로 정렬되므로 충분합니다. 구조체가 4 바이트의 * 홀수 * 배수로 정렬되면 첫 번째 멤버는 4 바이트로 정렬되지만 두 번째 멤버는 패딩으로 인해 정렬되지 않습니다. 동일한 메모리 레이아웃을 구조체의 모든 인스턴스에 제공하면서 정렬을 올바르게 수행하는 유일한 방법은 가장 큰 유형에 따라 정렬하는 것입니다. – hobbs

+0

실례합니다. 하지만 구조체가 4 바이트의 홀수 배수로 정렬되어 있다고해도 12 바이트라고 말하면 왜 처음에는 패딩이 필요한가요? 첫 번째 필드는 4 바이트를 차지할 것이고, 다음 필드는 완벽한 8 바이트 정렬 주소 인 16 번째 바이트에서 시작할 수 있습니다. 정렬은 데이터 멤버에게 여전히 적합합니다. 만약 내가 틀렸다면 나에게 정정하십시오. – gjain

관련 문제