Utilizzo CUDA da alcune settimane, ma ho qualche dubbio sull'assegnazione di blocchi/fili/filo. Sto studiando l'architettura da un punto di vista didattico (progetto universitario), quindi raggiungere il massimo delle prestazioni non è la mia preoccupazione.In che modo CUDA blocca/deforma/filtra la mappa sui core CUDA?
Prima di tutto, vorrei capire se ho ottenuto questi fatti dritto:
Il programmatore scrive un kernel, e organizzare la sua esecuzione in una griglia di blocchi di filettatura.
Ogni blocco è assegnato a un multiprocessore di flusso (SM). Una volta assegnato, non può migrare a un altro SM.
Ogni SM divide i propri blocchi in Warps (attualmente con una dimensione massima di 32 thread). Tutti i thread in un warp vengono eseguiti simultaneamente sulle risorse dell'SM.
L'esecuzione effettiva di un thread viene eseguita dai core CUDA contenuti nell'SM. Non esiste una mappatura specifica tra thread e core.
Se un warp contiene 20 thread, ma attualmente sono disponibili solo 16 core, il warp non verrà eseguito.
D'altra parte se un blocco contiene 48 thread, sarà diviso in 2 warps e verrà eseguito in parallelo a condizione che sia disponibile memoria sufficiente.
Se un thread inizia su un core, quindi viene bloccato per l'accesso alla memoria o per un'operazione a virgola mobile lunga, la sua esecuzione potrebbe riprendere su un core differente.
Sono corretti?
Ora, ho una GeForce 560 Ti quindi secondo le specifiche è dotata di 8 SM, ciascuna contenente 48 core CUDA (384 core in totale).
Il mio obiettivo è assicurarsi che ogni nucleo dell'architettura esegua le istruzioni SAME. Supponendo che il mio codice non richiederà più il registro di quelli disponibili in ogni SM, ho immaginato diversi approcci:
ho creare 8 blocchi di 48 thread ciascuno, in modo che ogni SM ha 1 blocco da eseguire. In questo caso i 48 thread verranno eseguiti in parallelo nell'SM (sfruttando tutti i 48 core disponibili per loro)?
C'è qualche differenza se lancio 64 blocchi di 6 thread? (Supponendo che verranno mappati in modo uniforme tra gli SM)
Se "immergo" la GPU in lavoro pianificato (creando 1024 blocchi di 1024 thread ciascuno, ad esempio) è ragionevole presumere che tutti i core saranno usato ad un certo punto e eseguirà gli stessi calcoli (supponendo che i fili non si fermino mai)?
C'è un modo per verificare queste situazioni utilizzando il profiler?
C'è qualche riferimento per questa roba?Ho letto la guida alla programmazione CUDA e i capitoli dedicati all'architettura hardware in "Programmazione di processori paralleli in parallelo" e "Progettazione e sviluppo di applicazioni CUDA"; ma non ho potuto ottenere una risposta precisa.
Grazie per la tua risposta. Leggo i riferimenti, ma ci sono alcune cose che non capisco nella tua risposta.Nelle seguenti domande presumo che stiamo usando un'architettura Fermi con 48 core (16 core * 3 "core group"): 1. Hai menzionato una mappatura tra core e laneid. Che tipo di mappatura è? 2. Dai riferimenti che ho ottenuto, ciascun "core group" esegue al massimo un half-warp (16 thread) per ciclo di clock. Quindi, in teoria, se abbiamo 48 thread nello stesso blocco, saranno organizzati in 3 mezzi mezzi warps e eseguiti in parallelo sui 48 core. Ho ragione? – Daedalus
I core CUDA sono il numero di unità FP di precisione singola. Pensare all'esecuzione in termini di core CUDA non è corretto. Ogni ordito ha 32 fili. Questi thread saranno rilasciati a un gruppo di unità di esecuzione (ad esempio 16 cuda core). Per emettere su tutti i 48 core in un singolo clock, uno dei due schedulatori di warp deve selezionare una distorsione che soddisfi il req di una coppia superscalare ed entrambe le istruzioni devono essere di un tipo eseguito dai core CUDA. Inoltre l'altro schedulatore di warp deve scegliere un ordito la cui prossima istruzione sarà eseguita dai core CUDA. –
Non è richiesto che gli orditi siano nello stesso blocco o che gli orditi in un blocco abbiano lo stesso contatore di programma. –