2014-10-31 9 views
8

Sto eseguendo un esperimento di accesso alla memoria in cui è stata utilizzata una matrice 2D con ogni riga delle dimensioni di una pagina di memoria. L'esperimento consiste nel leggere ogni elemento usando la riga/colonna principale e poi anche scrivere su ogni elemento usando la riga/colonna maggiore. La matrice a cui si accede è stata dichiarata con ambito globale per facilitare i requisiti di programmazione.Sta leggendo uno "zero" dalla memoria più velocemente della lettura di altri valori?

Il punto di questa domanda è che con la matrice di test dichiarata staticamente, i valori sono inizializzati a zero dal compilatore ei risultati che ho trovato erano piuttosto interessanti. Quando ho letto le operazioni di prima, vale a dire

rowMajor_read(); 
colMajor_read(); 
rowMajor_write(); 
colMajor_write(); 

Quindi la mia operazione colMajor_read finito molto in fretta. enter image description here

Tuttavia, se faccio le operazioni di scrittura prima della lettura che abbiamo:

rowMajor_write(); 
colMajor_write(); 
rowMajor_read(); 
colMajor_read(); 

enter image description here

E l'operazione di lettura column-major è aumentato di quasi un ordine di grandezza.

Ho pensato che deve avere qualcosa a che fare con il modo in cui il compilatore ottimizza il codice. Poiché la matrice globale era identicamente zero per ogni elemento, il compilatore ha rimosso completamente le operazioni di lettura? O è in qualche modo "più facile" leggere un valore dalla memoria che è identicamente zero?

Non si passano comandi speciali del compilatore per quanto riguarda le ottimizzazioni, ma ho dichiarato le mie funzioni in questo modo.

inline void colMajor_read(){ 
    register int row, col; 
    register volatile char temp __attribute__((unused)); 
    for(col = 0; col < COL_COUNT; col++) 
     for(row = 0; row < ROW_COUNT; row++) 
      temp = testArray[row][col]; 
} 

Perché ero in esecuzione in questioni in cui il compilatore completamente rimossa la variabile temp dalla funzione di cui sopra in quanto non è mai stato utilizzato. Penso che avere sia volatile sia __attribute__((unused)) sia ridondante, ma l'ho incluso comunque. Ho avuto l'impressione che non siano state implementate ottimizzazioni su una variabile volatile.

Qualche idea?


Ho esaminato l'assieme generato ei risultati sono identici per la funzione colMajor_read. La versione non in linea (assemblaggio): http://pastebin.com/C8062fYB

+5

La mia ipotesi è con la cache di sistema e la previsione. – Nit

+1

Concordo con @Nit. La località cache è molto probabilmente la fonte della varianza. Le cache possono facilmente dare un miglioramento del tempo di accesso 10x. Se si sospetta seriamente che il compilatore ottimizzi le operazioni di trasferimento (improbabile attraverso le funzioni, ma non strettamente impossibile), ottenere un output assembler delle funzioni C da verificare. –

+2

Aspetta ragazzi. Non penso che sia tutto così complicato. Poiché i metodi sono in linea, ciò significa che tutte queste funzioni si trovano all'interno della stessa unità di compilazione, quindi il compilatore può fare cose fantastiche. Principalmente, può dire se hai cambiato o meno la variabile dal momento della lettura e della scrittura, quindi potrebbe facilmente reinterpretare il codice come 'temp = 0;' che sarebbe pazzesco velocemente al confronto. Puoi pubblicare l'assemblea? – IdeaHat

risposta

7

Controllare l'utilizzo della memoria del processo prima e dopo aver scritto i valori sulla matrice. Se è memorizzato nella sezione .bss su Linux, ad esempio, le pagine azzerate verranno mappate su un'unica pagina di sola lettura con semantica copy-on-write. Quindi, anche se stai leggendo un sacco di indirizzi, potresti leggere la stessa pagina della memoria fisica più e più volte.

Questa pagina http://madalanarayana.wordpress.com/2014/01/22/bss-segment/ ha una buona spiegazione.

In questo caso, azzerare nuovamente la matrice in un secondo momento e rieseguire il test di lettura e non dovrebbe essere più veloce.

+0

+1 Stavo per postare questo quando ho notato che avevo 16 ore di ritardo. – Mehrdad

Problemi correlati