현재 메모리 페이지 크기 (sysconf(_SC_PAGESIZE)
에서 반환)를 사용하는 휴대용 C 프로그램을 작성 중입니다. 나는 페이지 크기가 비트 연산을 사용하는 효율적인 관리를 가능하게하는 2의 거듭 제곱이라는 것을 가장 잘 압니다. 그래도 어디서나이 보증을 찾지 못했습니다. 그렇다면 페이지 크기가 2의 힘이라고 가정하는 것이 얼마나 안전할까요? 이 조건을 만족시키지 못하는 아키텍처의 예가 있습니까?메모리 페이지 크기가 2의 거듭 제곱이라고 가정하는 것이 안전합니까?
답변
페이지 크기가 2의 거듭 제곱이어야한다는 명시적인 설명을 찾을 수는 없지만 매우 합리적인 가정이라고 생각합니다. POSIX의 "정렬"개념 (posix_memalign
참조)은 임의의 약수가 아니라 2의 제곱으로 정의됩니다. 구체적으로 정렬 인수는 sizeof(void*)
의 배수의 배수 여야합니다. 이 인터페이스로 페이지 정렬 메모리를 얻으십시오. 그 외에도 모든 실제 아키텍처는 두 페이지의 크기를 사용하며이를 변경하는 합리적인 근거가 없습니다. 하드웨어에서 비용이 많이 드는 것은 그 밖의 것입니다.
'memalign' 계열의 기능에 대해서는 몰랐습니다. 지금 나는 그들도 필요하다는 것을 안다. 감사! –
다른 모든 페이지 크기는 PMMU와 캐시의 매우 긴요 한 경로에서 실제 나눗셈/나머지를 요구합니다. 즉, x86, ARM, PPC, POWER, MIPS, SPARC, SuperH, ColdFire/68XXX 아키텍처는 2 페이지 크기의 모든 기능을 갖추고 있습니다. 나없이 하나만 보여 주면 매우 부러진 디자인을 보여줍니다 ... – Olaf
@VictorSchubert : 항상 가장 일반적인 기능을 사용하십시오. C 표준은 이미'aligned_alloc'을 제공합니다. posix-version을 사용할 필요가 없습니다 (이미 이식성 문제에 관해서 질문했습니다). 또한 구현에 의해 지원 될 필요는 없습니다. 맨 페이지에서 : "posix_memalign() 함수는 권고 정보 옵션의 일부이며 모든 구현에서 제공 할 필요는 없습니다." – Olaf
1) Linux 커널의 페이지 크기 계산을 통해 보장됩니다. 이것은 공식적인 표준이라는 의미에서 보증은 아니지만, 이미 언급 된 모든 이유로이 접근법이 바뀔 것 같지 않습니다. /usr/src/kernels/<your_kernel>/include/asm-generic/page.h
에서
: 당신이 볼 수 있듯이
#define PAGE_SHIFT 12
#ifdef __ASSEMBLY__
#define PAGE_SIZE (1 << PAGE_SHIFT)
#else
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#endif
는 페이지 크기는 실제로 항상 두 가지의 힘이 될 것입니다, 따라서 변화의 관점에서 정의된다. 이 코드는 일반 아키텍처의 경우에 사용되며 특정 아키텍처에서는 PAGE_SHIFT
에 대해 다른 값을 정의합니다.
2) 실용적인 측면에서 터미널에 getconf PAGESIZE
을 입력하여 getconf
프로그램을 통해 페이지 크기를 얻을 수 있습니다. 이것은 결코 사용되지 않는 백업 케이스를 코딩하는 것보다 훨씬 쉬운 빠른 컴파일 타임 검사를 생성하는 데 사용될 수 있습니다.
3) 페이지 크기는 MMU에 의해 결정됩니다. 따라서 공식적인 표준에 가장 가까이 다가 가려면 다양한 제조업체의 프로세서 설명서가 필요합니다. 예를 들어, 인텔 소프트웨어 개발자 설명서의 볼륨 3A에서 표 4-1 인텔 프로세서의 페이징 모드와 페이지 크기의 완전한 목록 제공 :
4) 내가 말할 수를 그 모든 주요 프로세서 아키텍처 2의 제곱 인 페이지 크기를 사용합니다.
5) 실제 메모리 공간의 단편화 - 실제로 그렇지 않은 경우 큰 문제가 있습니다. 페이지와 페이지 프레임 크기는 동일해야하므로, 페이지 크기가 두 배가 아닌 경우 페이지 프레임이 두 배가됩니다. 페이지 프레임 크기가 3000이고 (예를 들어 간단히하기 위해) 전체 페이지 프레임이 32 개라고 가정 해 보겠습니다. 따라서 물리적 주소는 17 비트 길이 - 페이지 프레임을 선택하는 데 5 비트 및 3000 바이트를 주소 지정하는 12 비트입니다.
00000 0000 0000 0000
\___/ \____________/
| \
(page frame) (page offset)
페이지의 사이즈 (페이지 프레임 크기)의 2의 거듭 제곱 같으면
후00000 0000 0000 0000
에서
11111 1111 1111 1111
되는 전체 물리 메모리 공간은 유효 주소이다. 페이지 프레임 크기가 3000 인 경우
XXXXX 1011 1011 0111
(마지막 유효한 주소)부터
XXXXX 1111 1111 1111
까지 실제 주소 공간에 차이가 있습니다. 그러한 시스템을 사용할 수 없다는 말은 아니지만 생각할 이유가없는 끔찍한 복잡성을 더할 수 있습니다.
x86은 모든 Linux 구현의 소수를 차지하며, 다른 운영 체제를 고려한 경우는 적습니다. 누군가가 2의 2의 페이지 크기 이외의 것을 구현한다고 가정 할 이유가 없다는 것에 동의하지만, 단일 CPU 문서는 거의 증명되지 않습니다. 마지막 단락은 약간 혼란 스럽습니다. 물리적 주소의 갭은 또한 논리적 인 공간에서의 갭일 수 있으며, 이는 견딜 수 없다. 그러나 (나머지와 함께) 나누면 둘 다 피할 수 있습니다. 그것은 단지 비용 (시간과 공간)의 배분 대 그러한 단위의 이익은 받아 들일 수 없을 것입니다. – Olaf
MMU는 조각난 물리적 메모리 공간 위에 논리적으로 일관된 가상 주소 공간을 제공하기 위해 항상 마술을 할 수 있으므로 가상 메모리 공간이 반드시 조각화되지는 않습니다. 물리적 인 기억은 그것의 주위에 얻을 수 없다. – David
내가 썼을 때, 그것은 마스킹 대신에 나머지를 포함하는 진정한 분리를 포함 할 것이다! 그리고 다른 모든 CPU 및 하드웨어 설계자가 확인할 수 있기 때문에 이것이 확실한 의미입니다! – Olaf
- 1. 왜 링 버퍼 크기가 2의 거듭 제곱이어야합니까?
- 2. 페이지 테이블 입력 크기 - 왜 2의 거듭?
- 3. 서버에 PHP 5가 있다고 가정하는 것이 안전합니까?
- 4. 이메일 주소가 고유하다고 가정하는 것이 안전합니까?
- 5. STL 벡터 스토리지가 항상 인접 해 있다고 가정하는 것이 안전합니까?
- 6. 크기가 2의 거듭 제곱이 아닌 정수는 의미가 있습니까?
- 7. 크기가 2의 거듭 제곱이 아닐 때 벡터 합계가 감소합니까?
- 8. opencv dft는 2의 거듭 제곱으로 이미지 크기가 올바르게 작동합니다.
- 9. 왜 InSampleSize가 2의 거듭 제곱이어야합니까?
- 10. 2의 거듭 제곱으로 플로트 결과
- 11. Integer가 VB.Net에서 항상 32 비트라고 가정하는 것이 안전합니까?
- 12. 브라우저에 일반적으로 설치되는 Java 버전은 1.4라고 가정하는 것이 안전합니까?
- 13. 경로 C : \ WINDOWS \ system32가 항상 있다고 가정하는 것이 안전합니까?
- 14. VB.net에서 메서드는 하위 또는 함수를 의미한다고 가정하는 것이 안전합니까?
- 15. ..stream :: int_type의 값이 eof를 제외하고> = 0이라고 가정하는 것이 안전합니까?
- 16. 코코아 : NSFilesPromisePboardType에 전달할 도착 URL이 파일 URL이라고 가정하는 것이 안전합니까?
- 17. Java에서 비트 연산의 기본 유형을 특정 크기로 가정하는 것이 안전합니까?
- 18. 항상 긍정적 인 것으로 errno를 가정하는 것이 안전합니까?
- 19. 가로 모드에서 높이가 항상 너비보다 작다고 가정하는 것이 안전합니까?
- 20. 포인터가 C에서 int의 크기라고 가정하는 것이 안전한가요?
- 21. 가상 메모리 페이지 정렬
- 22. 2의 거듭 제곱의 결과로 값 분해
- 23. 정수가 C에서 2의 거듭 제곱인지 확인
- 24. 2의 거듭 제곱의 합으로 숫자를 인쇄하십시오.
- 25. 2의 거듭 제곱에 가장 가까운 정수를 찾아
- 26. 사용자 입력에서 2의 거듭 제곱을 계산하십시오.
- 27. 샘플 크기가 2의 거듭 제곱이 아닌 비트 맵을 디코딩하는 방법은 무엇입니까?
- 28. 바로 가기를 작성하는 것이 안전합니까?
- 29. debug_kit.sqlite 파일을 삭제하는 것이 안전합니까?
- 30. socket.sendto가 비 블로킹 동작이라고 가정하는 것이 안전한가요?
MMU에는 구분선이 없지만 비트 마스킹을 사용하여 가상 주소를 테이블 워크 용 파트로 분할하므로 안전한 방법입니다. – Olaf
크기를 검색 할 수 있다고 생각하는 이유는 무엇입니까? – skrrgwasme
@skrrgwasme : 그의 알고리즘은 2의 거듭 제곱의 이점을 얻을 수 있습니다. 예를 들어 FFT가 있습니다. – Olaf