가상 주소 공간에서 페이지 크기는 어떻게 결정됩니까?


43

Linux는 모든 주소가 실제 주소가 아닌 가상 주소 인 가상 메모리 시스템을 사용합니다. 이 가상 주소는 프로세서에 의해 물리적 주소로 변환됩니다.

이 변환을 쉽게하기 위해 가상 메모리와 실제 메모리는 페이지로 나뉩니다. 각 페이지에는 고유 번호가 부여됩니다. 페이지 프레임 번호

일부 페이지 크기는 2KB, 4KB 등이 될 수 있습니다. 그러나이 페이지 크기 번호는 어떻게 결정됩니까? 아키텍처의 크기에 영향을 받습니까? 예를 들어, 32 비트 버스의 주소 공간은 4GB입니다.

답변:


56

다음 getconf명령을 통해 시스템 구성을 쿼리하여 시스템의 기본 페이지 크기를 찾을 수 있습니다 .

$ getconf PAGE_SIZE
4096

또는

$ getconf PAGESIZE
4096

참고 : 위의 단위는 일반적으로 바이트 단위이므로 4096은 4096 바이트 또는 4kB와 같습니다.

이것은 리눅스 커널의 소스에 고정되어 있습니다 :

$ more /usr/src/kernels/3.13.9-100.fc19.x86_64/include/asm-generic/page.h
...
...
/* PAGE_SHIFT determines the page size */

#define PAGE_SHIFT  12
#ifdef __ASSEMBLY__
#define PAGE_SIZE   (1 << PAGE_SHIFT)
#else
#define PAGE_SIZE   (1UL << PAGE_SHIFT)
#endif
#define PAGE_MASK   (~(PAGE_SIZE-1))

쉬프팅은 어떻게 4096을 제공합니까?

비트를 이동할 때 2의 이진수 곱셈을 수행합니다. 따라서 왼쪽 ( 1 << PAGE_SHIFT) 으로 비트를 이동 하면 2 ^ 12 = 4096의 곱셈이 수행됩니다.

$ echo "2^12" | bc
4096

2
최신 하드웨어는 2MB 및 일부 1GB 페이지 크기를 지원합니다. 커널 빌드의 기본값으로 2MB 페이지에 대해 "PAGE_SHIFT"를 21로 설정할 수 있습니까?
ReverseFlow

2
@ReverseFlow 그런 질문에 대답하기 위해 별도의 질문을 할 것입니다.
Kirill Bulygin

@sim, 왜 비트 조작이 사용되는지 궁금하십니까? 컴파일러는 일반적으로 곱셈을 비트 조작으로 변환하므로 동일한 성능을 제공한다는 것을 읽었습니다.
InAFlash

17

하드웨어 (특히 CPU의 일부인 MMU )에 따라 가능한 페이지 크기가 결정됩니다. 프로세서 레지스터 크기와는 관련이 없으며 주소 공간 크기와는 간접적 인 관계 만 있습니다 (MMU가 둘 다 결정 함).

거의 모든 아키텍처는 4kB 페이지 크기를 지원합니다. 일부 아키텍처는 더 큰 페이지를 지원하고 일부는 더 작은 페이지를 지원하지만 4kB는 매우 광범위한 기본값입니다.

리눅스는 두 가지 페이지 크기를 지원합니다 :

  • 모든 아키텍처에서 기본적으로 4kB라고 생각되는 보통 크기의 페이지이지만, 일부 아키텍처에서는 다른 값 (예 : ARM64의 경우 16kB 또는 IA64의 경우 16kB, 16kB 또는 64kB)을 사용할 수 있습니다. 이것들은 MMU (Linux가 PTE 라고 부르는 것 ) 에서 가장 깊은 수준의 디스크립터에 해당합니다 .
  • 컴파일 된 경우 거대한 페이지 ( CONFIG_HUGETLB_PAGE필요 CONFIG_HUGETLBFS하며 대부분의 용도로 사용). 이것은 두 번째로 깊은 MMU 디스크립터 레벨 (Linux가 PMD라고 부르는 것)에 해당합니다 (또는 일반적으로 모든 아키텍처에 적용되는지는 모르겠습니다).

페이지 크기는 메모리 사용량, 메모리 사용량 및 속도가 절충됩니다.

  • 페이지 크기가 클수록 페이지가 부분적으로 사용될 때 더 많은 낭비가 발생하므로 시스템 메모리가 더 빨리 소모됩니다.
  • 더 깊은 MMU 디스크립터 레벨은 페이지 테이블에 더 많은 커널 메모리를 의미합니다.
  • MMU 디스크립터 레벨이 깊을수록 페이지 테이블 순회에 더 많은 시간이 소요됩니다.

더 큰 페이지 크기의 이익은 대부분의 응용 프로그램에서 작지만 비용은 상당합니다. 이것이 대부분의 시스템이 보통 크기의 페이지 만 사용하는 이유입니다.

getconf유틸리티 또는 C 함수를 사용 하여 시스템의 (일반) 페이지 크기를 쿼리 할 수 ​​있습니다 sysconf.

$ getconf PAGE_SIZE
4096

거대한 페이지를 사용 하려면 hugetlbfs파일 시스템을 마운트하고 파일을 mmapping해야합니다.


참고 : 거대한 페이지를 사용하는 경우 hugetlbfs를 마운트 할 필요가 없습니다. 하단의 커널 문서 노트는 공유 메모리 호출이나 mmap 플래그를 사용할 수도 있습니다. 또한 더 흥미롭게도 투명한 대형 페이지를 활성화하면 커널이 모든 앱에서 가능한 경우 일반 페이지를 자동으로 대형 페이지로 변환합니다.
derobert

이것이 진정한 근본적인 답변입니다. Linux는 페이징 하드웨어를 잘 사용하도록 설계되었습니다. 페이징에 대한 자세한 내용 : stackoverflow.com/questions/18431261/how-does-x86-paging-work
치로 틸리新疆改造中心法轮功六四事件

0

페이지 크기는 대부분 프로세서 아키텍처에 따라 다릅니다. x86에서 보호 모드를 도입 한 386 프로세서의 시간부터 페이지 크기는 4 kB입니다.

x64 모드에서는 2MB 크기의 큰 페이지가있을 수도 있습니다. 그러나 그것들을 사용하는 것은 약간 복잡합니다.

Wikipedia 기사 에서 페이지 크기에 대한 자세한 정보를 찾을 수 있습니다.


0

프로세서가 사용 가능한 페이지 크기를 결정합니다. 대부분의 경우 x86 및 x86_64 프로세서에서 하드웨어 구현 페이지 크기는 4kb입니다. 그러나 원하는 경우 운영 체제에서 한 번에 여러 페이지를 할당하여 소프트웨어에서 8kb, 16kb 또는 32kb 페이지를 효과적으로 구현할 수 있습니다.

x86 및 x86_64 프로세서는 각각 표준 4kb 페이지와 함께 4mb 및 2mb 페이지를 혼합 할 수 있습니다. 이 기능이 전혀 사용되지 않으면 대부분 커널 공간을 할당하는 데 사용됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.