2013-03-20 16 views
16

Ok, so che le domande correlate sono state poste più e più volte e ho letto praticamente tutto ciò che ho trovato su questo, ma le cose non sono ancora chiare. Probabilmente anche perché ho trovato e letto cose che si contraddicevano a vicenda (forse perché, provenendo da tempi diversi, si riferivano a dispositivi con capacità di calcolo diverse, tra le quali sembra esserci un bel gap). Sto cercando di essere più efficiente, per ridurre il mio tempo di esecuzione e quindi ho bisogno di sapere esattamente quanti thread/warp/blocchi possono essere eseguiti contemporaneamente in parallelo. Inoltre stavo pensando di generalizzare questo e calcolare un numero ottimale di thread e blocchi da passare al mio kernel basandomi solo sul numero di operazioni che so di dover fare (per programmi più semplici) e sulle specifiche del sistema.CUDA Blocks & Warps

Ho una GTX 550Ti, btw con capacità di calcolo 2.1. 4 SMs x 48 core = 192 core CUDA.

Ok, quindi ciò che è chiaro per me è:

può più di 1 isolato run contemporaneamente (in parallelo) su un multiprocessore (SM)? Ho letto che fino a 8 blocchi possono essere assegnati a un SM, ma nulla su come vengono eseguiti. Dal fatto che il mio numero massimo di thread per SM (1536) è appena più grande del mio numero massimo di thread per block (1024), penserei che i blocchi non vengano eseguiti in parallelo (forse 1 e mezzo?). O almeno non se ho un numero massimo di discussioni su di loro. Inoltre, se imposto il numero di blocchi, diciamo 4 (il mio numero di SM), verranno inviati a un SM diverso ciascuno? Oppure non riesco davvero a controllare come tutto questo è distribuito sull'hardware e quindi questo è un punto controverso, il mio tempo di esecuzione varierà in base ai capricci del mio dispositivo ...

In secondo luogo, so che un blocco dividerà i suoi thread in gruppi di 32 thread che corrono in parallelo, chiamati warps. Ora questi orditi (presumendo che non abbiano alcuna relazione l'uno con l'altro) possono essere eseguiti parallelamente? Perché nell'architettura Fermi si afferma che 2 orditi vengono eseguiti contemporaneamente, inviando un'istruzione da ogni distorsione a un gruppo di 16 (?) Core, mentre da qualche altra parte leggo che ogni nucleo gestisce un ordito, che spiegherebbe i 1536 thread massimi (32 * 48) ma sembra un po 'troppo. 1 core CUDA può gestire 32 thread contemporaneamente?

In una nota più semplice, quello che sto chiedendo è: (per esempio) se voglio sommare 2 vettori in un terzo, quale lunghezza dovrei dare loro (nr di operazioni) e come dovrei dividerli in blocchi e thread per il mio dispositivo per funzionare contemporaneamente (in parallelo) a piena capacità (senza core inattivi o SM).

Mi dispiace se questo è stato chiesto prima e non ho capito o non l'ho visto. Spero che tu possa aiutarmi. Grazie!

risposta

15

La distribuzione e l'esecuzione parallela del lavoro sono determinati dalla configurazione di avvio e dal dispositivo. La configurazione di avvio indica le dimensioni della griglia, le dimensioni dei blocchi, i registri per thread e la memoria condivisa per blocco. Sulla base di queste informazioni e del dispositivo è possibile determinare il numero di blocchi e orditi che possono essere eseguiti contemporaneamente sul dispositivo. Quando si sviluppa un kernel, si guarda solitamente al rapporto tra gli orditi che possono essere attivi su SM e il numero massimo di orditi per SM per il dispositivo. Questo è chiamato l'occupazione teorica. Lo CUDA Occupancy Calculator può essere utilizzato per indagare su diverse configurazioni di lancio.

All'avvio di una griglia, il distributore del lavoro di calcolo rasterizza la griglia e distribuisce i blocchi di thread a SM e le risorse SM verranno allocate per il blocco di thread. Blocchi di thread multipli possono essere eseguiti simultaneamente su SM se l'SM ha risorse sufficienti.

Per avviare una distorsione, l'SM assegna l'ordito a un programma di curvatura e assegna i registri per l'ordito. A questo punto l'ordito è considerato un ordito attivo.

Ogni schedulatore di ordito gestisce un set di orditi (24 su Fermi, 16 su Kepler). I warp che non sono bloccati sono chiamati warp idonei. Ad ogni ciclo, lo scheduler di warp sceglie un warp e un'istruzione (e) per l'ordito idonei per unità di esecuzione quali unità int/fp, unità a virgola mobile a doppia precisione, unità di funzioni speciali, unità di risoluzione delle diramazioni e unità di carico. Le unità di esecuzione sono pipeline consentendo a molti orditi di avere 1 o più istruzioni in volo per ogni ciclo. Warp può essere bloccato su recupero delle istruzioni, dipendenze dei dati, dipendenze di esecuzione, barriere, ecc.

Ogni kernel ha una configurazione di avvio ottimale diversa. Strumenti come Nsight Visual Studio Edition e NVIDIA Visual Profiler possono aiutarti a ottimizzare la configurazione di avvio. Ti consiglio di provare a scrivere il codice in modo flessibile in modo da poter provare più configurazioni di avvio. Vorrei iniziare usando una configurazione che ti dà almeno il 50% di occupazione, quindi prova ad aumentare e diminuire l'occupazione.

risposte ad ogni domanda

D: È possibile più di 1 isolato run contemporaneamente (in parallelo) su un multiprocessore (SM)?

Sì, il numero massimo si basa sulla capacità di calcolo del dispositivo. See Tabe 10. Technical Specifications per Compute Capability : Maximum number of residents blocks per multiprocessor per determinare il valore. In generale, la configurazione di avvio limita il valore del tempo di esecuzione. Vedi il calcolatore di occupazione o uno degli strumenti di analisi NVIDIA per maggiori dettagli.

D: Dal fatto che il mio numero massimo di thread per SM (1536) è appena più grande del mio numero massimo di thread per blocco (1024), penserei che i blocchi non vengano eseguiti in parallelo (forse 1 e metà?).

La configurazione di avvio determina il numero di blocchi per SM. Il rapporto tra il numero massimo di thread per blocco e il numero massimo di thread per SM è impostato per consentire agli sviluppatori una maggiore flessibilità nel modo in cui partizionano il lavoro.

D: Se si imposta il numero di blocchi su, diciamo 4 (il mio numero di SM), verranno inviati a un SM diverso ciascuno? O non riesco davvero a controllare come tutto questo è distribuito sull'hardware e quindi questo è un punto controverso, il mio tempo di esecuzione varierà in base ai capricci del mio dispositivo ...

È possibile controllare limitato di distribuzione del lavoro. È possibile controllarlo artificialmente limitando l'occupazione allocando più memoria condivisa, ma questa è un'ottimizzazione avanzata.

Q: In secondo luogo, so che un blocco divide i suoi thread in gruppi di 32 thread che corrono in parallelo, chiamati warp. Ora questi orditi (presumendo che non abbiano alcuna relazione l'uno con l'altro) possono essere eseguiti parallelamente?

Sì, orditi possono essere eseguiti in parallelo.

Q: Perché nell'architettura Fermi afferma che 2 orditi vengono eseguiti contemporaneamente

Ogni Fermi SM ha 2 orditi schedulatori. Ogni schedulatore di ordito può inviare istruzioni per 1 ordito per ciclo. L'esecuzione delle istruzioni è sottoposta a pipeline in modo che molti orditi possano avere 1 o più istruzioni in volo in ogni ciclo.

Q: Invio di un'istruzione da ogni distorsione a un gruppo di 16 (?) Core, mentre da qualche altra parte ho letto che ogni core gestisce un curvatura, che spiegherebbe i 1536 thread max (32x48) ma sembra un po 'troppo . 1 core CUDA può gestire 32 thread contemporaneamente?

Sì. I core CUDA sono il numero di unità di esecuzione integer e floating point. L'SM ha altri tipi di unità di esecuzione che ho elencato sopra. GTX550 è un dispositivo CC 2.1. Ad ogni ciclo un SM ha il potenziale per spedire al massimo 4 istruzioni (128 thread) per ciclo. A seconda della definizione di esecuzione, i fili totali in volo per ciclo possono variare da molte centinaia a molte migliaia.

+0

Estendendo la domanda: * 1 Can CUDA nucleo ansa 32 thread contemporaneamente *, è necessario che questi 32 fili devono essere dello stesso bloccare? È possibile che un nucleo CUDA eseguire due filetti da diversi blocchi contemporaneamente – haccks

+0

nucleo A CUDA non è un "core", è un numero intero/floating point pipeline di esecuzione. Esiste una mappatura fissa tra l'id della riga del filetto (ptx% laneid) nel warp e le pipeline di esecuzione. Sui dispositivi CC 3.x 32 thread da un warp vengono inviati a un percorso di esecuzione int/fp 32-wide. Sui dispositivi CC 2.x 32 thread da un warp vengono inviati a un doppio percorso clocked in/fp di 16 ampiezze su 2 hot clock. L'unità a doppia precisione non è così ampia da causare problemi di curvatura su più cicli. Tutte le discussioni devono far parte dello stesso ordito. –

+0

Sì, lo so. Tutti i thread devono far parte dello stesso wrap. L'equivalente core della CPU in GPU è un SM ed esegue i thread in wraps (32 thread). Ogni SP elabora un thread. Ciò che mi confonde è che un SM può avere più di un residente di blocco, vale a dire che più blocchi di thread possono essere eseguiti simultaneamente su un multiprocessore. Se un SM ha 8 SP e può avere blocchi 8 residenti alla volta e ciascuna di blocco con 64 thread, quindi è necessario che nel primo ciclo 8 saranno trattati solo blocco? – haccks

-2

Uno dei concetti a cui è stato utile affondare è, per me, l'efficienza del supporto hardware per il cambio di contesto sul chip CUDA.

Di conseguenza, un interruttore di contesto si verifica su ogni accesso di memoria, consentendo ai calcoli di procedere per molti contesti alternativamente mentre gli altri attendono su questi accessi di memoria. nessuno dei modi in cui le architetture GPGPU raggiungono le prestazioni è la capacità di parallelizzare in questo modo, oltre a parallelizzare i nuclei dei multipli.

Le migliori prestazioni si ottengono quando nessun core è mai in attesa di accesso alla memoria e si ottiene contando solo un numero sufficiente di contesti per garantire che ciò accada.

+0

Questo non è vero. Lo scheduler di ordito può scegliere ogni ciclo per emettere istruzioni dall'insieme di deformazioni attive che sono idonee. Un ordito è ammissibile se non è bloccato a causa di una dipendenza esecuzione, la dipendenza dei dati, recuperare, ecc –

1

Sto cercando di essere più efficiente, per ridurre il mio tempo di esecuzione e quindi ho bisogno di sapere esattamente quanti thread/warp/blocchi possono essere eseguiti contemporaneamente in parallelo.

In breve, il numero di fili/orditi/blocchi che possono essere eseguiti contemporaneamente dipende da diversi fattori.La Guida alle migliori pratiche di CUDA C ha una recensione su Execution Configuration Optimizations che spiega questi fattori e fornisce alcuni suggerimenti per ragionare su come modellare la tua applicazione.