Sto facendo una ricerca per la mia Università relativa a un algoritmo di ricostruzione di immagini per uso medico.migliorare la località e ridurre l'inquinamento della cache in un'implementazione di ricostruzione di immagini mediche
Sono bloccato in qualcosa fino a 3 settimane, ho bisogno di migliorare le prestazioni del seguente codice:
for (lor=lor0[mypid]; lor <= lor1[mypid]; lor++)
{
LOR_X = P.symmLOR[lor].x;
LOR_Y = P.symmLOR[lor].y;
LOR_XY = P.symmLOR[lor].xy;
lor_z = P.symmLOR[lor].z;
LOR_Z_X = P.symmLOR[lor_z].x;
LOR_Z_Y = P.symmLOR[lor_z].y;
LOR_Z_XY = P.symmLOR[lor_z].xy;
s0 = P.a2r[lor];
s1 = P.a2r[lor+1];
for (s=s0; s < s1; s++)
{
pixel = P.a2b[s];
v = P.a2p[s];
b[lor] += v * x[pixel];
p = P.symm_Xpixel[pixel];
b[LOR_X] += v * x[p];
p = P.symm_Ypixel[pixel];
b[LOR_Y] += v * x[p];
p = P.symm_XYpixel[pixel];
b[LOR_XY] += v * x[p];
// do Z symmetry.
pixel_z = P.symm_Zpixel[pixel];
b[lor_z] += v * x[pixel_z];
p = P.symm_Xpixel[pixel_z];
b[LOR_Z_X] += v * x[p];
p = P.symm_Ypixel[pixel_z];
b[LOR_Z_Y] += v * x[p];
p = P.symm_XYpixel[pixel_z];
b[LOR_Z_XY] += v * x[p];
}
}
per chi vuole conoscere, il codice implementa la funzione in avanti MLEM e tutti le variabili sono FLOAT.
Dopo diversi test, ho notato che il grosso ritardo era su questa parte del codice. (lo sai, la regola 90 - 10).
In seguito, ho usato Papi (http://cl.cs.utk.edu/papi/) per misurare le mancanze della cache L1D. Come pensavo, Papi conferma che le prestazioni diminuiscono a causa di una maggiore quantità di miss, in particolare per l'accesso casuale al vettore b (di enormi dimensioni).
Leggere informazioni su Internet Conosco solo due opzioni per migliorare le prestazioni finora: migliorare la localizzazione dei dati o ridurre l'inquinamento dei dati.
a fare il primo miglioramento, cercherò di modificare il codice per essere cache di conoscenza, proprio come è stato propossed da Ulrich Drepper su Ciò che ogni programmatore dovrebbe conoscere la memoria (www.akkadia.org/drepper/ cpumemory.pdf) A.1 Matrix moltiplicazione.
Credo che il blocco della SpMV (moltiplicazione di matrice-vettore multiplo) migliorerà le prestazioni.
D'altra parte, ogni volta che il programma ha tentato di accedere al vettore b, abbiamo avuto l'inquinamento della cache .
C'è un modo per caricare un valore dal vettore b con l'istruzione SIMD senza utilizzare la cache?
Inoltre, è possibile utilizzare una funzione come void _mm_stream_ps (float * p, __m128 a) per memorizzare un valore float sul vettore b senza inquinare la cache?
Non riesco a utilizzare _mm_stream_ps perché memorizza sempre 4 float ma l'accesso al vettore b è chiaramente casuale.
Spero di essere chiaro nel mio dilemma.
Ulteriori informazioni: v è il valore della colonna di un archivio Sparse Matrix con formato CRS. Mi rendo conto che si potrebbe fare un'altra ottimizzazione se provassi a cambiare il formato CRS ad altri, tuttavia, come ho detto prima, avevo fatto diversi test per mesi e so che la diminuzione delle prestazioni è legata all'accesso casuale al vettore b. da 400.000.000 L1D Misses posso andare a 100 ~ Manca quando non immagazzino nel vettore b.
Grazie.
+1 per una domanda ben formata con molte informazioni di base e dettagli su ciò che hai provato fino ad ora. –