2010-11-04 24 views
5

Ho esaminato la guida alla programmazione e alle best practice e ho menzionato che l'accesso alla memoria globale richiede 400-600 cicli. Non ho visto molto sugli altri tipi di memoria come la cache delle texture, la cache costante, la memoria condivisa. I registri hanno 0 latenza di memoria.Quanti cicli di latenza della memoria per tipo di accesso alla memoria in OpenCL/CUDA?

Penso che la cache costante sia la stessa dei registri se tutti i thread utilizzano lo stesso indirizzo nella cache costante. Nel peggiore dei casi non ne sono così sicuro.

La memoria condivisa è uguale a quella dei registri purché non vi siano conflitti bancari? Se ci sono allora come si svolge la latenza?

E per quanto riguarda la cache delle texture?

risposta

4

La latenza delle memorie condivise/costanti/texture è piccola e dipende dal dispositivo in uso. In generale, anche se le GPU sono progettate come un'architettura di throughput, il che significa che creando abbastanza thread la latenza delle memorie, inclusa la memoria globale, è nascosta.

Il motivo per cui le guide parlano della latenza della memoria globale è che la latenza è di ordini di grandezza superiore a quella di altre memorie, il che significa che è la latenza dominante da considerare per l'ottimizzazione.

Hai menzionato la cache costante in particolare. Hai ragione a dire che se tutti i thread all'interno di un warp (cioè un gruppo di 32 thread) accedono allo stesso indirizzo, non c'è penalità, cioè il valore viene letto dalla cache e trasmesso a tutti i thread simultaneamente. Tuttavia, se i thread accedono a indirizzi diversi, gli accessi devono serializzare poiché la cache può fornire solo un valore alla volta. Se stai usando CUDA Profiler, questo verrà mostrato sotto il contatore di serializzazione.

La memoria condivisa, a differenza della cache costante, può fornire una larghezza di banda molto più elevata. Controlla il discorso CUDA Optimization per maggiori dettagli e una spiegazione dei conflitti bancari e del loro impatto.

+0

Vale ancora la pena utilizzare la cache costante se, ad esempio, tutti i thread accedono a 1000 float? Sarebbe come un 1000 legge da un registro? La guida dice che l'uso della cache costante in questo modo scala linearmente giusto? – smuggledPancakes

+0

Se tutti i thread accedono allo stesso * valore * in una determinata iterazione di un ciclo, è possibile utilizzare la cache costante. La cache costante fornirà alcuni vantaggi a causa della località spaziale (su Fermi la cache L1 può ottenere la stessa cosa ma lascia L1 libera per altri dati). Detto questo, bersaglio principalmente Fermi e non uso mai '__constant__', uso solo const molto e lascia che sia il compilatore a capirlo! Per esempio nel tuo caso io passerei il kernel arg come 'const float * const myfloatarray'. Suggerirei sempre di eseguire Visual Profiler per verificare la presenza di serializzazioni nel caso in cui vi siate persi qualcosa. – Tom

+0

Si potrebbe aggiungere che le linee di cache sono 128byte (32byte) per L1 (L2), quindi stiamo parlando di indirizzi che cadono nelle stesse linee (non necessariamente gli stessi indirizzi). Alcuni numeri su altre latenze possono essere trovati [qui] (http://stackoverflow.com/questions/6744101/fermi-l2-cache-hit-latency). –

6

Per (Keplero) Tesla K20 le latenze sono i seguenti:

memoria globale: 440 orologi
memoria costante
        L1: 48 orologi
        L2: 120 orologi
Memoria condivisa: 48 orologi
Memoria trama
        L1: 108 orologi
        L2: 240 orologi

Come faccio a saperlo? Ho eseguito i microbenchmarks descritti dagli autori di Demystifying GPU Microarchitecture through Microbenchmarking. Forniscono risultati simili per la GTX 280 precedente.

Questo è stato misurato su un cluster Linux, il nodo di elaborazione su cui stavo eseguendo i benchmark non è stato utilizzato da altri utenti o eseguito altri processi. È BULLX linux con una coppia di 8 core Xeon e 64 GB di RAM, nvcc 6.5.12. Ho modificato il sm_20 in sm_35 per la compilazione.

C'è anche un capitolo operands cost in PTX ISA anche se non è molto utile, semplicemente ribadisce ciò che ci si aspetta, senza fornire cifre precise.

+0

Anche io sto usando Tesla K20 e ho provato a eseguire lo stesso microbenchmark che hai menzionato. Sei riuscito a lanciare 'global.cu' senza problemi? Chiedo perché sto affrontando un problema con accessi illegali alla memoria - Ho postato questa domanda [qui] (http://stackoverflow.com/questions/36416843/how-to-write-a-pointer-chasing-benchmark-using- 64-bit-puntatori-a-cuda). Mi stavo chiedendo se hai apportato qualche modifica al codice del kernel per farlo funzionare per te? – Kajal

+0

@ kv.333 E 'stato qualche tempo fa. Ricordo che c'erano alcuni problemi e non tutti i benchmark funzionavano. Non ricordo quali sono però. –

Problemi correlati