source

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

manysource 2023. 6. 19. 21:42

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

요즘 RAM 용량이 매우 커서 4GB보다 큰 메모리를 하나 할당할 수 있습니까?아니면 여러 개의 작은 청크를 할당하여 청크 간의 전환을 처리해야 합니까?

왜요? 저는 오픈 스트리트맵 xml 데이터를 처리하는 일을 하고 있는데 이 파일들은 매우 큽니다.한 덩어리에 다 실을 수 없어서 지금 스트리밍 중인데 malloc이나 new 상한선이 궁금해서요.

단답: 그럴 가능성은 없습니다.

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

이론적으로는 가능하지만 메모리 할당기에 대한 설명서를 읽어야 합니다.또한 메모리 조각화 문제에 더 취약할 수 있습니다.

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

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

64비트 CPU 및 O/S 빌드가 필요하며 작업 세트의 스레싱을 방지하기에 충분한 메모리가 필요합니다.약간의 배경:

32비트 시스템(일반적으로)에는 2^32(4,294,967,296)의 고유 값 중 하나를 저장할 수 있는 레지스터가 있습니다.즉, 32비트 포인터는 마법의 4GB 제한이 발생하는 2^32 고유 메모리 위치 중 하나를 처리할 수 있습니다.

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

자세한 내용은 설명하지 않지만프레젠테이션(경고: Powerpoint)에서는 이 기능에 대해 설명합니다.일부 운영 체제에는 MMU를 조작하고 사용자 수준 제어 하에 서로 다른 물리적 위치를 가상 주소 공간으로 스왑할 수 있는 기능(위의 FP 덕분에 여기에 설명된 기능 등)이 있습니다.

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

즉, 오버레이에서 수동으로 스왑하려면 윈도우즈의 PAE 기능 또는 Linux의 동등한 기능을 명시적으로 사용해야 합니다.꼭 그렇게 힘들지는 않지만, 일을 시작하려면 시간이 좀 걸릴 것입니다.

또는 메모리가 많은 64비트 박스를 구입할 수 있으며 이러한 문제는 거의 해결됩니다.64비트 포인터가 있는 64비트 아키텍처는 적어도 이론적으로는 2^64(18,446,744,073,709,551,616)의 고유 주소로 연속적인 데이터 구조를 구축할 수 있습니다.따라서 더 큰 규모의 연속 데이터 구조를 구축하고 관리할 수 있습니다.

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

64비트 OS(및 메모리가 많은 컴퓨터)에서는 문제가 되지 않습니다.

만약 malloc가 대처할 수 없다면 OS는 메모리를 직접 할당할 수 있는 API를 제공할 것입니다.윈도우즈에서 VirtualAlloc API를 사용할 수 있습니다.

사용하는 C 컴파일러와 (물론) 플랫폼에 따라 다르지만 연속적으로 사용 가능한 메모리의 가장 큰 덩어리를 할당할 수 없는 근본적인 이유는 없습니다. 필요한 것보다 적을 수도 있습니다.물론 64비트 시스템을 사용하여 RAM보다 더 많은 용량을 처리해야 할 수도 있습니다.

역사와 자세한 내용은 Malloc을 참조하십시오.

alloc.h에서 HipMax를 호출하여 사용 가능한 최대 블록 크기를 가져옵니다.

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

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

32비트 Windows의 경우 포인터 크기가 32비트이기 때문에 4GB보다 큰 단일 청크를 얻을 수 없으므로 가상 주소 공간을 4GB로 제한할 수 있습니다. (4GB 이상의 메모리를 얻으려면 물리적 주소 확장을 사용할 수 있지만, 해당 메모리를 4GB의 가상 주소 공간에 직접 매핑해야 합니다.)

64비트 윈도우즈의 경우 VC++ 컴파일러는 가상 주소 공간을 이론적으로 8TB로 제한하는 64비트 포인터를 지원합니다.

Linux/gcc - 32비트는 허용하지 않지만 64비트는 허용합니다.

Rob이 지적했듯이 VirtualAlloc for 윈도우즈는 익명 사용자 파일 매핑과 마찬가지로 이를 위한 좋은 옵션입니다.그러나, 특히 당신의 질문과 관련하여, "만약 C 또는 C++이 할당될 수 있다면"에 대한 대답은 "아니오 이것은 WIN7 RC 64에서도 지원되지 않습니다"입니다.

exe 파일의 PE/COFF 규격에서 HIP 예약 및 HIP 커밋을 지정하는 필드는 32비트 수량입니다.이는 윈도우즈 CRT에서 현재 힙 구현의 물리적 크기 제한(4GB가 조금 부족함)과 일치합니다.따라서 C/C++에서 4GB 이상을 할당할 수는 없습니다(CreateFileMapping 및 VirtualAlloc/VirtualAllocNuma 등의 OS 지원 기능에 대해 기술적으로 설명).C 또는 C++가 아닙니다.

또한 페이지 테이블의 기본 x86 또는 amd64 ABI 구조가 있다는 점에 유의하십시오.WILL은 실질적으로 당신이 우려하는 바를 수행하며, 당신의 더 큰 요청에 더 작은 청크를 할당합니다. 이것이 커널 메모리에서 발생하더라도, 전체 시스템에 영향을 미치며, 이러한 테이블은 유한합니다.

메모리를 이렇게 방대하게 할당하는 경우에는 할당 세분성(VirtualAlloc에서 적용)을 기반으로 할당하고 더 큰 페이지를 사용할 수 있도록 선택적인 플래그나 메서드를 식별하는 것이 좋습니다.

4kb 페이지는 386의 초기 페이지 크기였으며 이후 펜티엄에 4MB가 추가되었습니다.현재 AMD64(AMD Family 10h Processor용 소프트웨어 최적화 가이드)는 최대 페이지 테이블 항목 크기가 1GB입니다.이는 프로세스의 메모리를 찾아 할당하고 권한을 부여하기 위해 커널의 디렉토리에 4개의 고유 항목만 있으면 된다는 것을 의미합니다.

Microsoft는 또한 애플리케이션 메모리의 세부 사항과 Vista/2008 플랫폼 이상에 대한 사용 방법을 설명하는 이 설명서를 릴리스했습니다.

Contents

Introduction. 4

About the Memory Manager 4

Virtual Address Space. 5

Dynamic Allocation of Kernel Virtual Address Space. 5

Details for x86 Architectures. 6

Details for 64-bit Architectures. 7

Kernel-Mode Stack Jumping in x86 Architectures. 7

Use of Excess Pool Memory. 8

Security: Address Space Layout Randomization. 9

Effect of ASLR on Image Load Addresses. 9

Benefits of ASLR.. 11

How to Create Dynamically Based Images. 11

I/O Bandwidth. 11

Microsoft SuperFetch. 12

Page-File Writes. 12

Coordination of Memory Manager and Cache Manager 13

Prefetch-Style Clustering. 14

Large File Management 15

Hibernate and Standby. 16

Advanced Video Model 16

NUMA Support 17

Resource Allocation. 17

Default Node and Affinity. 18

Interrupt Affinity. 19

NUMA-Aware System Functions for Applications. 19

NUMA-Aware System Functions for Drivers. 19

Paging. 20

Scalability. 20

Efficiency and Parallelism.. 20

Page-Frame Number and PFN Database. 20

Large Pages. 21

Cache-Aligned Pool Allocation. 21

Virtual Machines. 22

Load Balancing. 22

Additional Optimizations. 23

System Integrity. 23

Diagnosis of Hardware Errors. 23

Code Integrity and Driver Signing. 24

Data Preservation during Bug Checks. 24

What You Should Do. 24

For Hardware Manufacturers. 24

For Driver Developers. 24

For Application Developers. 25

For System Administrators. 25

Resources. 25

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

다른 모든 사람들이 말했듯이, 64비트 기계를 갖는 것이 최선의 방법입니다.그러나 32비트 시스템 인텔 시스템에서도 OS와 CPU가 PAE를 지원하는 경우 4GB 이상의 메모리 영역을 처리할 수 있습니다.안타깝게도 32bit WinXP는 이 기능을 수행하지 않습니다(32bit Vista는 작동합니까?Linux를 사용하면 기본적으로 이 작업을 수행할 수 있지만 포인터가 여전히 32비트이므로 mmap()을 사용하더라도 4GB 영역으로 제한됩니다.

하지만 여러분이 해야 할 일은 운영 체제가 여러분을 대신하여 메모리 관리를 하도록 하는 것입니다.RAM을 충분히 처리할 수 있는 환경에서 XML 파일을 데이터 구조로 읽어 들여 공간을 할당할 수 있습니다.그런 다음 XML 파일 자체에서 작동하는 대신 메모리의 데이터 구조에서 작동합니다.

하지만 64비트 시스템에서도 OS와 MMU가 직접 처리하기 때문에 프로그램의 어떤 부분이 실제로 RAM, 캐시에 저장되어 있는지 또는 디스크에 호출되어 있는지에 대한 제어가 거의 불가능합니다.

언급URL : https://stackoverflow.com/questions/181050/can-you-allocate-a-very-large-single-chunk-of-memory-4gb-in-c-or-c