2013-04-04 8 views
6

Sono nuovo a High Performance Computing e la mia prima domanda in questo forum in cui sono stato un lettore per molto tempo.Operazione aritmetica su array statici molto grandi in C/C++

Fondamentalmente ho bisogno di fare operazioni aritmetiche su matrici molto grandi come ad esempio

double variable [9][4][300][300][300] (uninitialized) 

caso 1: Se dichiarare la matrice di cui sopra come local/automatic allora ottengo errore runtime se avevo compilato senza ottimizzazione come "g++ file.cpp" .. (l'errore è colpa di segmentazione - overflow dello stack ???)

caso 2: Nello stesso caso, come sopra, se ho avuto compi le con ottimizzazione il codice viene eseguito come previsto. "g++ -O2 file.cp p"(è il array in bss ora ???)

caso 3: Se faccio la variabile global/static allora compila bene ma comunque non funziona e dà solo un messaggio 'killed' sul terminale e termina.

non esiste un vero problema, ma io sono curioso e vogliono imparare cosa succede quando estremamente grandi array sono dichiarati e dove risiedono in memoria a seconda del loro tipo di dati.

sono anche consapevole del metodo per generare questi array in fase di esecuzione usando malloc o nuovo. Quindi ovviamente sarebbe in ordine.

Quindi la domanda più importante per me è -> che è il metodo più efficiente (vale a dire più piccolo di run-time durante il calcolo degli array in memoria) di trattare con grandi array quando si compila con g++ e in esecuzione su linux clusters.

Grazie per la vostra pazienza per la lettura.

+1

Questo array è pura follia. È necessario utilizzare una soluzione più intelligente per elaborare quella quantità di dati a meno che la piattaforma di destinazione non sia una sorta di macchina bestiale. Dal momento che sembra non essere il caso, in streaming i dati dal disco in blocchi o qualcosa di simile. –

+0

Questi array sono inevitabili. Rappresentano le variabili nello spazio a 4 dimensioni. E le operazioni di memoria risolvono l'equazione differenziale non lineare complessa. E alla fine il codice verrà eseguito su un cluster di 50 nodi con più di 100 GB di memoria. I dati sono infatti letti dal disco.La mia curiosità è nel capire dove si trovano questi dati in fase di esecuzione e in quale sezione (bss/stack/heap) si otterrebbero prestazioni di runtime più veloci. – physicist

+1

Ti consiglio davvero di fare il tuo lavoro basandoti su alcune librerie matematiche come armadillo o BLAS. QUALSIASI COSA tu faccia e intendo QUALSIASI COSA, è impossibile battere le prestazioni di queste librerie. Considerate di usarli fin dall'inizio :) – amas

risposta

7

Le variabili locali saranno sempre nello stato nello stack, indipendentemente dalle bandiere di ottimizzazione. E quella matrice sarà di circa 7 gigabyte! Molto più grande di qualsiasi pila possibile.

La dimensione può anche essere un motivo che non si avvia, come se lo metti come una variabile globale/static, allora avete bisogno di avere più di 7 GB o memoria virtuale libera e contigua per essere in grado per caricare anche il programma.

+0

Quindi per il caso 2 (dalla domanda) l'array è ancora in pila. Pensavo che lo stack avesse un limite di dimensioni di 8kb? Ti ho capito bene? Non ho dato alcuna opzione di compilazione per aumentare il limite di stack. – physicist

+2

A meno che la variabile non sia ottimizzata, non è da nessuna parte. –

+1

@physicist Lo stack sulla maggior parte dei sistemi moderni è compreso tra 1 e 4 megabyte. Potrebbero esserci dei flag che puoi passare al linker per certi sistemi per cambiarlo, ma poi lo stack avrà quella dimensione per l'intero programma e il più delle volte solo una frazione (probabilmente meno del mezzo percento di quel 7GB) sarà Usato. Un enorme spreco di memoria. Esistono modi migliori per gestire dataset di grandi dimensioni su un normale PC domestico, ad esempio la mappatura della memoria di un file. –

3

mi permetto di suggerire qualcosa sulla falsariga di:

typedef double slice[300][300][300]; 

std::vector<slice> variable[9] = { 4, 4, 4, 4, 4, 4, 4, 4, 4 }; 

In questo modo ogni vettore di 4 slice oggetti saranno assegnati in modo dinamico, il contenuto dei 9 vettori non devono essere contigui tra loro, e lo stack il consumo è sufficiente per i metadati per 9 vettori.

+0

che è un approccio interessante. fammi provare e vederlo grazie. – physicist