Domanda

Con quantità molto elevate di RAM in questi giorni mi chiedevo, è possibile allocare un singolo pezzo di memoria che è più grande di 4 GB? O avrei bisogno di allocare un gruppo di pezzi più piccoli e gestire il passaggio tra di loro?

Perché ??? Sto lavorando per elaborare alcuni dati XML di openstreetmap e questi file sono enormi. Al momento li sto trasmettendo in streaming dal momento che non riesco a caricarli tutti in un unico pezzo, ma mi sono solo incuriosito i limiti superiori di malloc o nuovi.

È stato utile?

Soluzione

Risposta breve: non probabile

Affinché ciò funzioni, dovresti assolutamente utilizzare un processore a 64 bit. In secondo luogo, dipenderebbe dal supporto del sistema operativo per allocare più di 4G di RAM a un singolo processo.

In teoria, sarebbe possibile, ma dovresti leggere la documentazione per l'allocatore di memoria. Saresti anche più suscettibile ai problemi di frammentazione della memoria.

Ci sono buone informazioni su Gestione della memoria di Windows .

Altri suggerimenti

Un primer sui layout di memoria fisica e virtuale

Avresti bisogno di una CPU a 64 bit e build O / S e quasi sicuramente abbastanza memoria per evitare il thrashing del tuo working set. Un po 'di background:

Una macchina a 32 bit (nel complesso) ha registri che possono memorizzare uno di 2 ^ 32 (4.294.967.296) valori univoci. Ciò significa che un puntatore a 32 bit può indirizzare una qualsiasi di 2 ^ 32 posizioni di memoria univoche, da cui proviene il limite magico di 4 GB.

Alcuni sistemi a 32 bit come SPARCV8 o Xeon hanno MMU che tirano fuori un trucco per consentire più memoria fisica. Ciò consente a più processi di occupare memoria per un totale di oltre 4 GB in totale, ma ogni processo è limitato al proprio spazio di indirizzi virtuali a 32 bit. Per un singolo processo che guarda uno spazio di indirizzi virtuale, solo 2 ^ 32 posizioni fisiche distinte possono essere mappate da un puntatore a 32 bit.

Non entrerò nei dettagli ma Questa presentazione (attenzione: powerpoint) descrive come funziona. Alcuni sistemi operativi dispongono di servizi (come quelli descritti Qui - grazie a FP sopra) per manipolare la MMU e scambiare diverse posizioni fisiche nello spazio degli indirizzi virtuali sotto il controllo a livello di utente.

Il sistema operativo e gli I / O associati alla memoria occuperanno parte dello spazio degli indirizzi virtuali, quindi non tutti quei 4 GB sono necessariamente disponibili per il processo. Ad esempio, per impostazione predefinita Windows assume 2 GB di questo, ma può essere impostato su 1 GB solo se l'opzione / 3G viene richiamata all'avvio. Ciò significa che un singolo processo su un'architettura a 32 bit di questo tipo può solo costruire una struttura di dati contigua di memoria leggermente inferiore a 4 GB.

Ciò significa che dovresti usare esplicitamente il PAE servizi su Windows o Servizi equivalenti su Linux per scambiare manualmente gli overlay. Questo non è necessariamente così difficile, ma ci vorrà del tempo per funzionare.

In alternativa puoi ottenere un box a 64 bit con molta memoria e questi problemi scompaiono più o meno. Un'architettura a 64 bit con puntatori a 64 bit può costruire una struttura di dati contigua con un massimo di 2 ^ 64 (18.446.744.073.709.551.616) indirizzi univoci, almeno in teoria. Ciò consente di creare e gestire strutture dati contigue più grandi.

Il vantaggio dei file mappati in memoria è che puoi aprire un file molto più grande di 4 GB (quasi infinito su NTFS!) e avere più finestre di memoria da 4 GB in esso.
È molto più efficace dell'apertura di un file e della sua lettura in memoria, sulla maggior parte dei sistemi operativi utilizza il supporto di paging incorporato.

Questo non dovrebbe essere un problema con un sistema operativo a 64 bit (e una macchina che ha tanta memoria).

Se malloc non riesce a farcela, il sistema operativo fornirà certamente API che ti consentono di allocare memoria direttamente. In Windows è possibile utilizzare l'API VirtualAlloc .

dipende da quale compilatore C stai usando e da quale piattaforma (ovviamente) ma non c'è motivo fondamentale per cui non puoi allocare la più grande porzione di memoria contigua disponibile - che potrebbe essere inferiore al necessario. E, naturalmente, potresti dover utilizzare un sistema a 64 bit per indirizzare più di RAM ...

vedi Malloc per storia e dettagli

chiama HeapMax in alloc.h per ottenere la dimensione del blocco più grande disponibile

Hai preso in considerazione l'utilizzo di file mappati in memoria? Dato che stai caricando file davvero enormi, sembra che questo potrebbe essere il modo migliore di procedere.

Dipende dal fatto che il sistema operativo fornisca uno spazio di indirizzi virtuale che consenta di indirizzare la memoria oltre 4 GB e che il compilatore supporti l'allocazione usando new / malloc.

Per Windows a 32 bit non sarà possibile ottenere un singolo blocco più grande di 4 GB, poiché la dimensione del puntatore è di 32 bit, limitando così lo spazio di indirizzi virtuale a 4 GB. (È possibile utilizzare Estensione dell'indirizzo fisico per ottenere di più rispetto alla memoria da 4 GB; tuttavia, credo che tu debba mappare quella memoria nello spazio di indirizzo virtuale di 4 GB da solo)

Per Windows a 64 bit, il compilatore VC ++ supporta puntatori a 64 bit con limite teorico dello spazio di indirizzi virtuali a 8 TB.

Sospetto che lo stesso valga per Linux / gcc - 32 bit non te lo consente, mentre 64 bit te lo consente.

Come ha sottolineato Rob, VirtualAlloc per Windows è una buona opzione per questo, così come un mapping di file anonymouse. Tuttavia, in particolare per quanto riguarda la tua domanda, la risposta a "se C o C ++" può allocare, la risposta è NO QUESTO NON È SUPPORTATO ANCHE SU WIN7 RC 64

Nella specifica PE / COFF per i file exe, il campo che specifica la riserva HEAP e il commit HEAP è una quantità a 32 bit. Ciò è in linea con i limiti di dimensione fisica dell'attuale implementazione di heap in Windows CRT, che è appena inferiore a 4 GB. Pertanto, non è possibile allocare più di 4 GB da C / C ++ (tutte le funzionalità di supporto del sistema operativo di CreateFileMapping e VirtualAlloc / VirtualAllocNuma ecc ... non sono C o C ++).

Inoltre, ESSERE AWARE che ci sono costrutti ABI x86 o amd64 sottostanti noti come tabella delle pagine. Questo SARÀ in effetti fa ciò di cui sei preoccupato, allocando blocchi più piccoli per la tua richiesta più grande, anche se questo è felice nella memoria del kernel, c'è un effetto sul sistema complessivo, queste tabelle sono finite.

Se stai allocando memoria in tali grandiose proporzioni, ti consigliamo di allocarlo in base alla granularità di allocazione (che VirtualAlloc applica) e anche di identificare flag o metodi opzionali per abilitare pagine più grandi.

Le pagine da 4kb erano le dimensioni iniziali della pagina per il 386, in modo secondario il pentium ha aggiunto 4MB. Oggi, il AMD64 (Guida all'ottimizzazione del software per AMD Famiglia 10h Processors) ha una dimensione massima di immissione nella tabella delle pagine di 1 GB. Questo significa per il tuo caso qui, diciamo che hai appena fatto 4 GB, richiederebbe solo 4 voci univoche nella directory del kernel per individuare \ assegnare e autorizzare la memoria del tuo processo.

Microsoft ha anche rilasciato questo manuale che articola alcuni dei punti più fini della memoria dell'applicazione ed è utilizzabile per la piattaforma Vista / 2008 e successive.

Contenuto

Introduzione. 4

Informazioni su Memory Manager 4

Spazio di indirizzi virtuali. 5

Allocazione dinamica di Kernel Virtual Spazio degli indirizzi. 5

Dettagli per architetture x86. 6

Dettagli per architetture a 64 bit. 7

Stack in modalità kernel che salta in x86 Architetture. 7

Utilizzo della memoria della piscina in eccesso. 8

Sicurezza: layout dello spazio degli indirizzi Randomizzazione. 9

Effetto dell'ASLR sul caricamento dell'immagine Indirizzi. 9

Vantaggi di ASLR .. 11

Come creare in modo dinamico Immagini. 11

Larghezza di banda I / O. 11

Microsoft SuperFetch. 12

Scritture di file di paging. 12

Coordinamento di Memory Manager e Cache Manager 13

Clustering stile prefetch. 14

Gestione file di grandi dimensioni 15

Ibernazione e standby. 16

Advanced Video Model 16

Supporto NUMA 17

Assegnazione delle risorse. 17

Nodo predefinito e affinità. 18

Interrompere l'affinità. 19

Funzioni di sistema compatibili con NUMA Applicazioni. 19

Funzioni di sistema compatibili con NUMA Driver. 19

Paging. 20

Scalabilità. 20

Efficienza e parallelismo. 20

Numero di frame di pagina e database PFN. 20

Pagine grandi. 21

Allocazione pool allineato alla cache. 21

Macchine virtuali. 22

Bilancio del carico. 22

Ottimizzazioni aggiuntive. 23

Integrità del sistema. 23

Diagnosi di errori hardware. 23

Integrità del codice e firma dei driver. 24

Conservazione dei dati durante i controlli dei bug. 24

Cosa dovresti fare. 24

Per i produttori di hardware. 24

Per gli sviluppatori di driver. 24

Per gli sviluppatori di applicazioni. 25

Per gli amministratori di sistema. 25

Risorse. 25

Se size_t è maggiore di 32 bit sul tuo sistema, hai eliminato il primo ostacolo. Ma gli standard C e C ++ non sono responsabili per determinare se una determinata chiamata a new o malloc ha esito positivo (tranne malloc con dimensione 0). Dipende interamente dal sistema operativo e dallo stato attuale dell'heap.

Come hanno detto tutti gli altri, ottenere una macchina a 64 bit è la strada da percorrere. Ma anche su una macchina Intel a 32 bit, puoi indirizzare aree di memoria superiori a 4 GB se il tuo sistema operativo e la tua CPU supportano PAE . Sfortunatamente, WinXP a 32 bit non lo fa (fa Vista a 32 bit?). Linux ti consente di farlo per impostazione predefinita, ma sarai limitato a aree da 4 GB, anche con mmap () poiché i puntatori sono ancora a 32 bit.

Quello che dovresti fare, però, è lasciare che il sistema operativo si occupi della gestione della memoria per te. Entra in un ambiente in grado di gestire tanta RAM, quindi leggi i file XML in (a) strutture di dati e lascia che ti occupi lo spazio. Quindi operare sulla struttura dei dati in memoria, invece di operare sul file XML stesso.

Anche nei sistemi a 64 bit, tuttavia, non avrai molto controllo su quali parti del tuo programma si trovano effettivamente nella RAM, nella cache o sono paginate su disco, almeno nella maggior parte dei casi, dal momento che il sistema operativo e gli MMU gestiscono questo da soli.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top