Sto provando a compilare un file C++ grande 5,7 MB. Sto costruendo un eseguibile Linux a 64 bit su un sistema Linux a 64 bit. g ++ 4.7.2 purtroppo non è cooperativo:Compilando una mappa più grande (~ 6 MB) inizializzando il file C++ con gcc
g++: internal compiler error: Killed (program cc1plus)
Osservare con top
indica che il processo raggiunge circa 2,2 giga di memoria prima che ciò accada. Ho provato a impostare --param gcc-min-expand=0
e ho anche giocato con --param gcc-min-heapsize
ma questo non risolve il problema. Disabilitare l'ottimizzazione con -O0
non è stato d'aiuto.
Ho anche provato a compilare con clang, ma i risultati erano simili. Segmentato dopo aver superato anche 2 gigabyte di memoria. Non ho provato nessuna opzione extra con clang perché non sono così familiare con esso.
Il file sorgente in questione è costituito dall'inizializzazione in stile C++ 11 di alcune mappe.
typedef std::map<std::string, int> StringToIntMap;
StringToIntMap someData = {{"SOMESTRING", 1}, ..};
quello che voglio è preferibilmente di compilare il file con gcc, anche se clang può funzionare, invece, posso anche vivere con essa. Sarebbe anche utile scoprire, da qualcuno che conosce gli interni, cosa sta succedendo dietro le quinte. Se ho una mappa di 300.000 elementi in cui le stringhe sono lunghe circa 5 byte e corrisponde a uno int
corrisponde a pochi megabyte di dati e non riesco a immaginare facilmente come l'inizializzatore salta fino al punto di richiedere gigabyte compilare.
E per anticipare i commenti che non dovrei avere un file sorgente così grande. So che posso leggere i dati da un file di dati in fase di esecuzione, e questo è ciò che il programma fa ora, ma il mio caso d'uso è tale che il tempo di esecuzione del programma è il fattore più importante.
lol. Sono sicuro che l'appendice B dello standard dà al compilatore il permesso di iniziare a fallire un po 'prima di quello:/ – sehe
Spostare questo nel codice sorgente non guadagnerà molto nella realtà. Al momento, è necessario il tempo M per caricare il tempo eseguibile + N per inizializzare le mappe. Con i dati pre-caricati ti ritroverai con un eseguibile che richiede (circa) il tempo di caricamento M + N. Data paginazione richiesta, ciò avverrà come tempo M per iniziare l'esecuzione e N volta per pagina nei dati in fase di esecuzione. Ultima differenza: molto più lavoro, ma quasi nessuna differenza nella velocità di esecuzione. –
@JerryCoffin Ora se questo fosse un 'boost :: flatmap', potrebbe essere molto meglio, ma anche in questo caso, l'inizializzazione' constexpr' potrebbe essere migliore. – sehe