C 또는 C++에서 매우 큰 단일 메모리 청크(> 4GB)를 할당할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/181050

  •  05-07-2019
  •  | 
  •  

문제

요즘 램 용량이 너무 많아서 4GB보다 큰 단일 메모리 청크를 할당하는 것이 가능한지 궁금합니다.아니면 여러 개의 작은 청크를 할당하고 이들 간의 전환을 처리해야 합니까?

왜???일부 openstreetmap xml 데이터를 처리하는 중인데 이 파일이 엄청납니다.하나의 청크로 모두 로드할 수 없기 때문에 현재 스트리밍 중인데 malloc이나 new의 상한이 궁금합니다.

도움이 되었습니까?

해결책

짧은 대답 : 가능성이 없습니다

이것이 작동하기 위해 가지다 64 비트 프로세서를 사용합니다. 둘째, 4G 이상의 RAM을 단일 프로세스에 할당하기위한 운영 체제 지원에 달려 있습니다.

이론적으로는 가능할 것이지만 메모리 할당자를위한 문서를 읽어야합니다. 또한 메모리 조각화 문제에 더 취약 할 것입니다.

좋은 정보가 있습니다 Windows 메모리 관리.

다른 팁

물리적 및 가상 메모리 레이아웃에 대한 입문서

작업 세트의 스래싱을 ​​방지하려면 64비트 CPU 및 O/S 빌드와 거의 확실히 충분한 메모리가 필요합니다.약간의 배경지식:

32비트 머신에는 2^32(4,294,967,296)개의 고유 값 중 하나를 저장할 수 있는 레지스터가 있습니다.즉, 32비트 포인터는 2^32개의 고유 메모리 위치 중 하나를 처리할 수 있으며, 여기서 마법의 4GB 제한이 발생합니다.

SPARCV8 또는 Xeon과 같은 일부 32비트 시스템에는 더 많은 물리적 메모리를 허용하는 트릭을 가져오는 MMU가 있습니다.이를 통해 여러 프로세스가 총 4GB가 넘는 메모리를 차지할 수 있지만 각 프로세스는 자체 32비트 가상 주소 공간으로 제한됩니다.가상 주소 공간을 살펴보는 단일 프로세스의 경우 2^32개의 고유한 물리적 위치만 32비트 포인터로 매핑될 수 있습니다.

자세한 내용은 다루지 않겠습니다만 이 프레젠테이션 (경고:powerpoint)에서는 이것이 어떻게 작동하는지 설명합니다.일부 운영 체제에는 다음과 같은 기능이 있습니다. 여기 - 위의 FP 덕분에) MMU를 조작하고 사용자 수준 제어 하에 다양한 물리적 위치를 가상 주소 공간으로 교환합니다.

운영 체제 및 메모리 매핑된 I/O는 가상 주소 공간의 일부를 차지하므로 프로세스에서 4GB 전체를 반드시 사용할 수 있는 것은 아닙니다.예를 들어 Windows에서는 기본적으로 2GB를 사용하지만 부팅 시 /3G 스위치가 호출되는 경우 1GB만 사용하도록 설정할 수 있습니다.이는 이러한 종류의 32비트 아키텍처에서 단일 프로세스가 메모리에서 4GB 미만의 연속 데이터 구조만 구축할 수 있음을 의미합니다.

이는 명시적으로 PAE Windows의 시설 또는 Linux의 동등한 기능 오버레이를 수동으로 교체합니다.이것이 반드시 그렇게 어려운 것은 아니지만, 작업을 시작하는 데 시간이 좀 걸릴 것입니다.

또는 메모리가 많은 64비트 상자를 구입할 수 있으며 이러한 문제는 어느 정도 사라집니다.64비트 포인터가 있는 64비트 아키텍처는 적어도 이론적으로는 최대 2^64(18,446,744,073,709,551,616)개의 고유 주소로 연속 데이터 구조를 구축할 수 있습니다.이를 통해 더 큰 연속 데이터 구조를 구축하고 관리할 수 있습니다.

메모리 매핑 파일의 장점은 4GB보다 훨씬 더 큰 파일을 열 수 있고 (NTFS에서 거의 무한대) 여러 <4GB 메모리 창을 가질 수 있다는 것입니다.
파일을 열고 메모리로 읽는 것보다 훨씬 효과적입니다. 대부분의 운영 체제에서 내장 페이징 지원을 사용합니다.

이것은 64 비트 OS (및 메모리가 많은 기계)에서 문제가되지 않아야합니다.

Malloc이 대처할 수 없다면 OS는 확실히 메모리를 직접 할당 할 수있는 API를 제공합니다. 창문 아래에서 사용할 수 있습니다 VirtualAlloc API.

사용중인 C 컴파일러와 어떤 플랫폼 (물론)에 따라 다르지만, 가장 큰 인접하게 사용 가능한 메모리를 할당 할 수없는 근본적인 이유는 없습니다. 물론 많은 RAM보다 해결하기 위해 64 비트 시스템을 사용해야 할 수도 있습니다.

보다 Malloc 역사와 세부 사항을 위해

전화 heapmax Alloc.h에서 가장 큰 블록 크기를 얻으려면

메모리 매핑 파일 사용을 고려해 보셨습니까? 당신이 정말로 거대한 파일을로드하고 있기 때문에 이것이 가장 좋은 방법 인 것 같습니다.

OS가 4GB 이상의 메모리 주소를 허용하는 가상 주소 공간을 제공할지 여부와 컴파일러가 새/malloc을 사용하여 할당하는 것을 지원하는지 여부에 따라 다릅니다.

32 비트 창의 경우 포인터 크기가 32 비트이므로 가상 주소 공간을 4GB로 제한하기 때문에 4GB보다 큰 단일 청크를 얻을 수 없습니다. (사용할 수 있습니다 물리적 주소 확장 4GB 이상의 메모리를 얻기 위해; 그러나 나는 당신이 그 메모리를 4GB의 VirtualAddress 공간에 매핑해야한다고 생각합니다)

64 비트 Wind

나는 Linux/GCC에 대해서도 동일한 적용을 적용한다고 생각합니다.-32 비트는 당신을 허용하지 않는 반면, 64 비트는 당신을 허용합니다.

Rob이 지적했듯이 Windows 용 VirtualAlloc은 익명의 파일 매핑과 마찬가지로이를위한 좋은 옵션입니다. 그러나 구체적으로 귀하의 질문과 관련하여 "C 또는 C ++"에 대한 답은 할당 할 수 있습니다. 아니오 이것은 Win7 RC 64에서도 지원되지 않습니다.

EXE 파일의 PE/COFF 사양에서 힙 예약 및 힙 커밋을 지정하는 필드는 32 비트 수량입니다. 이것은 4GB에 불과한 Windows CRT의 현재 힙 구현의 물리적 크기 제한과 인라인입니다. 따라서 C/C ++에서 4GB 이상을 할당하는 방법은 없습니다 (기술적 인 CreateFilemapping 및 VirtualAlloc/VirtualAllocNuma 등의 OS 지원 기능은 C 또는 C ++가 아닙니다).

또한, BE 알고 있는 기본 x86 또는 AMD64 ABI Construct가 페이지 테이블로 알려져 있습니다. 이것 할 것이다 사실상, 당신이 걱정하는 것을하고, 더 큰 요청에 더 작은 청크를 할당하십시오. 이것은 커널 메모리에서 행복하지만 전체 시스템에 영향을 미치고 있으며,이 테이블은 유한합니다.

그러한 웅장한 목적에 메모리를 할당하는 경우, 할당 세분성 (VirtualAlloc가 집행)을 기반으로 할당하고 더 큰 페이지를 활성화하기위한 선택적 플래그 또는 메소드를 식별하는 것이 좋습니다.

4KB 페이지는 386의 초기 페이지 크기였으며, 펜티엄은 4MB를 추가했습니다. 오늘, AMD64 (AMD Family 10H 프로세서의 소프트웨어 최적화 안내서)의 최대 페이지 테이블 항목 크기는 1GB입니다. 이것은 당신의 사례에 대한 평균입니다. 4GB를했다고 가정 해 봅시다. 프로세스의 메모리를 위치시키고 허가하기 위해 커널 디렉토리에 4 개의 고유 한 항목 만 있으면됩니다.

Microsoft도 이것을 발표했습니다 수동 이는 애플리케이션 메모리의 더 미세한 점을 분명히 표현하며 Vista/2008 플랫폼 및 새로 사용됩니다.

내용물

소개. 4

메모리 관리자 4

가상 주소 공간. 5

커널 가상 주소 공간의 동적 할당. 5

X86 아키텍처에 대한 세부 사항. 6

64 비트 아키텍처에 대한 세부 사항. 7

x86 아키텍처에서 커널 모드 스택 점프. 7

초과 풀 메모리 사용. 8

보안 : 주소 공간 레이아웃 무작위 배정. 9

이미지로드 주소에 대한 ASLR의 영향. 9

ASLR의 이점. 11

동적 기반 이미지를 만드는 방법. 11

I/O 대역폭. 11

Microsoft Superfetch. 12

페이지 파일이 씁니다. 12

메모리 관리자 및 캐시 관리자의 조정 13

프리 페치 스타일 클러스터링. 14

큰 파일 관리 15

최대 절전 모드 및 대기. 16

고급 비디오 모델 16

Numa 지원 17

자원 할당. 17

기본 노드 및 친화력. 18

친화력을 중단하십시오. 19

응용 프로그램에 대한 Numa-Aware 시스템 기능. 19

운전자를위한 Numa-Aware 시스템 기능. 19

페이징. 20

확장 성. 20

효율성과 병렬성 .. 20

페이지 프레임 번호 및 PFN 데이터베이스. 20

큰 페이지. 21

캐시 정렬 풀 할당. 21

가상 머신. 22

로드 밸런싱. 22

추가 최적화. 23

시스템 무결성. 23

하드웨어 오류 진단. 23

코드 무결성 및 드라이버 서명. 24

버그 확인 중 데이터 보존. 24

해야 할 일. 24

하드웨어 제조업체 용. 24

운전자 개발자를 위해. 24

응용 프로그램 개발자를 위해. 25

시스템 관리자를 위해. 25

자원. 25

시스템에서 size_t가 32비트보다 크면 첫 번째 장애물을 해결한 것입니다.그러나 C 및 C++ 표준은 new 또는 malloc에 ​​대한 특정 호출이 성공하는지 여부를 결정하는 데 책임이 없습니다(크기가 0인 malloc 제외).이는 전적으로 OS와 힙의 현재 상태에 따라 달라집니다.

다른 사람들이 말했듯이, 64 비트 기계를 얻는 것은 갈 길입니다. 그러나 32 비트 머신 인텔 머신에서도 OS와 CPU 지원이면 메모리 영역보다 4GB보다 큰 문제를 해결할 수 있습니다. Pae. 불행히도, 32 비트 WinXP는 이것을 수행하지 않습니다 (32 비트 비스타?). Linux를 사용하면 기본적으로이를 수행 할 수 있지만 포인터가 여전히 32 비트이므로 MMAP ()가 있더라도 4GB 영역으로 제한됩니다.

그래도해야 할 일은 운영 체제가 메모리 관리를 처리하게하는 것입니다. 많은 RAM을 처리 할 수있는 환경에 들어가서 XML 파일을 (a) 데이터 구조로 읽고 공간을 할당하도록하십시오. 그런 다음 XML 파일 자체에서 작동하는 대신 메모리의 데이터 구조에서 작동합니다.

64 비트 시스템에서도 OS와 MMU 핸들이기 때문에 프로그램의 일부가 실제로 RAM, 캐시에 있거나 캐시에 또는 디스크에 페이징되는 것을 많이 제어 할 수 없습니다. 이 자체.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top