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


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.