2014-02-09 1 views
3

나는 C#에서 관리되지 않는 코드에 대해 읽기, 다음 줄을 건너 온 한 -팩 크기 란 무엇입니까?

를 C# 프로그램의 CLR에서 오프셋 사용하여 필드 토큰을 찾습니다.
C 필드 이름은 직접 오프셋으로 컴파일됩니다. 액세스 속도의 경우 각 필드는 필드 크기의 배수 인 오프셋에 배치됩니다.
그러나 배율은 최대 x 바이트로 제한됩니다. 여기서 x는 "팩 크기"입니다.

제 질문은 팩 크기 란 무엇입니까?

답변

2

컴퓨터 아키텍처에서는 일을 byte aligned으로하는 것이 훨씬 빠릅니다. 언어 스펙이 팩 크기에 대해 이야기 할 때, 컴파일러는 사물이 어떻게 정렬되는지에 따라 데이터 크기를위한 더 큰 슬롯을 자동으로 만들 것이라고 말하고 있습니다. 즉, 2 바이트 필드로 생각할 때가 실제로 메모리의 4 바이트 슬롯에있을 수 있습니다. 스토리지 크기를 줄이려면, CPU 속도가 느려지는 대신에 팩 크기를 조정할 수 있습니다.

자세한 내용은 팩의 msdn을 확인하십시오.

tutorial을 인용하면

역사적 메모리는 바이트 어드레스 가능하고 순차적으로 배치. 메모리가 1 바이트 너비의 단일 뱅크로 배열되어있는 경우 프로세서 은 정수를 가져 오기 위해 4 개의 메모리 읽기 사이클을 발행해야합니다. 하나의 메모리 사이클에서 4 바이트의 정수를 모두 읽는 것이 더 경제적입니다 ( ). 이러한 장점을 취하기 위해 메모리는 위의 그림에 표시된 과 같은 4 개의 뱅크 그룹으로 정렬됩니다.

메모리 주소 지정은 여전히 ​​순차적입니다. 뱅크 0이 주소 X를 차지하면 뱅크 1, 뱅크 2 및 뱅크 3은 (X + 1), (X + 2) 및 (X + 3) 주소에있게됩니다. 4 바이트의 정수가 X 주소 (X는 4의 배수)에 할당되면 프로세서는 전체 정수를 읽는 메모리주기가 하나만 필요합니다. 도 아래에 나타낸 바와 같이 으로 정수가 4의 배수 이외 어드레스에 할당되어있는 경우

는, 상기 뱅크의 행에 걸쳐있는 두. 이러한 정수는 데이터를 가져 오기 위해 두 개의 메모리 읽기주기가 필요합니다. 방식에

...

변수의 데이터 정렬 계약이 은행 에 저장된 데이터. 예를 들어, 32 비트의 컴퓨터에서 int의 자연 정렬은 4 바이트입니다. 데이터 유형이 자연스럽게 정렬되면 CPU는 을 최소 읽기 주기로 가져옵니다.

마찬가지로, short int의 자연 정렬은 2 바이트입니다. 즉, short int는 뱅크 0 - 뱅크 1 쌍 또는 뱅크 2 - 뱅크 3 쌍에 저장 될 수 있습니다. 두 배는 8 바이트를 필요로하며 메모리의 두 행을 차지합니다. 뱅크. double의 잘못된 정렬은 double 데이터를 가져 오기 위해 두번 이상의 읽기 사이클을 수행합니다. .

이중 변수는 32 비트 머신에서 8 바이트 경계에 할당되며 두 개의 메모리 읽기 사이클이 필요합니다. 64 비트 시스템에서는 뱅크 수에 따라 을 사용하므로 double 변수는 8 바이트의 경계에 할당되며 단 하나의 메모리 읽기주기 만 필요합니다.

언어가 다르지만, 개념은 동일

4

내가 같이 필드의 위치 맞춤의 세부 사항을 것입니다 주어진, devshorts '인용에 덮여. 팩 크기 설정은 너무 커서 컴파일러가 필드 정렬을 유지하려고 시도하는 것을 중지합니다.

네이티브 코드의 컴파일러 설정 또는 #pragma입니다. 인텔 프로세서에 대한 까다로운 문제는 융통성이 있으며 불균형 한 데이터를 허용하기 때문입니다. 팩 크기 8은 매우 일반적인 기본값이며 거의 항상 올바른 값입니다. 때로는 1 또는 4입니다. [StructLayout] 선언의 Pack 속성이 일치해야합니다. 그렇지 않으면 잘못된 메모리 위치에서 필드를 읽게되므로 가비지를 읽을 확률이 높아집니다.

관련 문제