Domanda

Quando si scrivono applicazioni CUDA, è possibile lavorare a livello di driver oa livello di runtime, come illustrato in questa immagine (le librerie sono CUFFT e CUBLAS per la matematica avanzata):

 Modello di livello CUDA
(fonte: tomshw.it )

Suppongo che il compromesso tra i due sia un aumento delle prestazioni per l'API di basso livello ma a costo di una maggiore complessità del codice. Quali sono le differenze concrete e ci sono cose significative che non puoi fare con l'API di alto livello?

Sto usando CUDA.net per l'interoperabilità con C # ed è costruito come una copia dell'API del driver. Questo incoraggia a scrivere molto codice piuttosto complesso in C # mentre l'equivalente in C ++ sarebbe più semplice usando l'API di runtime. C'è qualcosa da vincere facendolo in questo modo? L'unico vantaggio che posso vedere è che è più facile integrare la gestione intelligente degli errori con il resto del codice C #.

È stato utile?

Soluzione

Il runtime CUDA consente di compilare e collegare i kernel CUDA in file eseguibili. Ciò significa che non è necessario distribuire i file cubin con l'applicazione o gestire il caricamento tramite l'API del driver. Come hai notato, è generalmente più facile da usare.

Al contrario, l'API del driver è più difficile da programmare, ma fornisce un maggiore controllo sull'utilizzo di CUDA. Il programmatore deve occuparsi direttamente di inizializzazione, caricamento del modulo, ecc.

È possibile richiedere informazioni più dettagliate sul dispositivo tramite l'API del driver rispetto all'API di runtime. Ad esempio, la memoria libera disponibile sul dispositivo può essere interrogata solo tramite l'API del driver.

Dalla Guida del programmatore CUDA:

  

È composto da due API:

     
      
  • Un'API di basso livello chiamata API del driver CUDA,
  •   
  • Un'API di livello superiore chiamata API di runtime CUDA che è implementata in cima   l'API del driver CUDA.
  •   
     

Queste API si escludono a vicenda: un'applicazione deve utilizzare una o l'altra   altro.

     

Il runtime CUDA semplifica la gestione del codice del dispositivo fornendo implicito   inizializzazione, gestione del contesto e gestione del modulo. Il codice host C.   generato da nvcc si basa sul runtime CUDA (vedere la Sezione 4.2.5), quindi   le applicazioni che si collegano a questo codice devono utilizzare l'API di runtime CUDA.

     

Al contrario, l'API del driver CUDA richiede più codice, è più difficile da programmare e   debug, ma offre un migliore livello di controllo ed è indipendente dalla lingua poiché solo   tratta gli oggetti cubini (vedere la Sezione 4.2.5). In particolare, è più difficile   configurare e avviare i kernel utilizzando l'API del driver CUDA, dall'esecuzione   i parametri di configurazione e kernel devono essere specificati con chiamate di funzione esplicite   anziché la sintassi della configurazione dell'esecuzione descritta nella Sezione 4.2.3. Inoltre, dispositivo   l'emulazione (vedere la Sezione 4.5.2.9) non funziona con l'API del driver CUDA.

Non vi è alcuna differenza di prestazioni evidente tra le API. Come i tuoi kernel usano la memoria e come sono disposti sulla GPU (in orditi e blocchi) avrà un effetto molto più pronunciato.

Altri suggerimenti

Ho scoperto che per la distribuzione di librerie in applicazioni multi-thread, il controllo sul contesto CUDA fornito dall'API del driver era fondamentale. La maggior parte dei miei clienti desidera integrare l'accelerazione GPU nelle applicazioni esistenti e oggigiorno quasi tutte le applicazioni sono multi-thread. Poiché non potevo garantire che tutto il codice GPU fosse inizializzato, eseguito e deallocato dallo stesso thread, ho dovuto utilizzare l'API del driver.

I miei tentativi iniziali con varie soluzioni alternative nell'API di runtime hanno portato a un errore, a volte in modo spettacolare: ho scoperto di poter riavviare ripetutamente e istantaneamente una macchina eseguendo solo il set errato di chiamate CUDA da thread diversi.

Da quando abbiamo migrato tutto sull'API del driver, tutto è andato bene.

J

un paio di cose importanti da notare:

innanzitutto le differenze tra le API si applicano solo al codice lato host. I kernel sono esattamente gli stessi. sul lato host la complessità dell'api del driver è piuttosto banale, le differenze fondamentali sono:

in api del driver hai accesso a funzionalità che non sono disponibili in api di runtime come i contesti.

l'emulatore funziona solo con il codice scritto per l'API di runtime.

oh e attualmente cudpp che è una libreria molto utile funziona solo con l'API di runtime.

Esistono alcuni problemi reali con l'allineamento degli argomenti e l'API del driver. Consulta la documentazione di CUDA 2.2 beta (o successive) per ulteriori informazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top