2010-02-05 4 views
16

Ho una certa familiarità con il visual profiler CUDA e il foglio di calcolo sull'occupazione, anche se probabilmente non sto sfruttando il più possibile. Profiling & L'ottimizzazione del codice CUDA non è come la profilatura del codice & per l'ottimizzazione del codice che gira su una CPU. Quindi spero di imparare dalle tue esperienze su come ottenere il massimo dal mio codice.Come si profila e si ottimizzano i kernel CUDA?

C'è stato un post che cercava il codice più veloce possibile per identificare self numbers e ho fornito un CUDA implementation. Non sono soddisfatto del fatto che questo codice sia il più veloce possibile, ma non riesco a capire sia le domande giuste che lo strumento da cui ottenere le risposte.

Come identificate i modi per rendere più veloci i kernel di CUDA?

risposta

21

Se stai sviluppando su Linux, il Visual Profiler di CUDA ti offre un sacco di informazioni, sapendo che cosa fare con esso può essere un po 'complicato. Su Windows è anche possibile utilizzare CUDA Visual Profiler oppure (su Vista/7/2008) è possibile utilizzare Nexus che si integra perfettamente con Visual Studio e fornisce informazioni sul profilo host e GPU combinate.

Una volta ottenuti i dati, è necessario sapere come interpretarli. La presentazione Advanced CUDA C di GTC ha alcuni suggerimenti utili. Le cose principali a cui prestare attenzione sono:

  • Accesso ottimale alla memoria: è necessario sapere cosa si aspetta che il codice faccia e quindi cercare le eccezioni. Quindi, se si caricano sempre float e ogni thread carica un float diverso da un array, ci si aspetterebbe di vedere solo carichi a 64 byte (su h/w correnti). Qualsiasi altro carico è inefficiente. Le informazioni di profilazione probabilmente miglioreranno in futuro h/w.
  • Minimizza serializzazione: il contatore "warp serialize" indica che hai conflitti di memoria condivisi o serializzazione costante, la presentazione va più nel dettaglio e cosa fare al riguardo come l'SDK (ad esempio il campione di riduzione)
  • Sovrapposizione I/O e calcolo: è qui che Nexus brilla davvero (è possibile ottenere manualmente le stesse informazioni utilizzando cudaEvents), se si dispone di una grande quantità di trasferimento dati si desidera sovrapporre il calcolo e l'I/O
  • Configurazione di esecuzione: il calcolatore di occupazione può essere d'aiuto, ma sono molto utili metodi semplici come commentare il calcolo per misurare la larghezza di banda attesa e misurata (e viceversa per il throughput del calcolo)

Questo è solo un inizio, controlla la presentazione di GTC e gli altri webinar sul sito Web NVIDIA.

+0

Grazie, Tom. Questa presentazione è disponibile per il download? –

+1

È lo stesso a cui mi sono collegato prima! http://www.nvidia.com/content/GTC/videos/GTC09-1086.flv http://www.nvidia.com/content/GTC/videos/GTC09-1086.mp4 – Tom

+0

Grazie, Tom. Non ho visto la tua risposta al mio commento l'altro giorno, immagino. –

0

Il profiler CUDA è piuttosto grezzo e non fornisce molte informazioni utili. L'unico modo per ottimizzare seriamente il tuo codice (supponendo che tu abbia già scelto il miglior algoritmo possibile) è avere una profonda comprensione dell'architettura della GPU, in particolare per quanto riguarda l'uso della memoria condivisa, i modelli di accesso alla memoria esterna, l'uso del registro, l'occupazione del thread , orditi, ecc.

Forse potresti inserire qui il tuo codice del kernel e ottenere un feedback?

Il forum nVidia CUDA developer forum è anche un buon posto dove chiedere aiuto per questo tipo di problema.

0

ho appeso indietro perché io non sono esperto CUDA, e le altre risposte sono piuttosto buone se il codice è già abbastanza vicino ottimale. Nella mia esperienza, questo è un grande IF, e non c'è nulla di male nel verificarlo.

Per verificarlo, è necessario scoprire se il codice non è sicuro di fare qualcosa che non ha davvero bisogno di fare. Qui ci sono modi che posso vedere per verificare che:

  • Eseguire lo stesso codice sul processore di vaniglia, e prendere stackshots di esso, o utilizzare un profiler come Oprofile o RotateRight/Zoom che può darvi informazioni equivalenti .

  • Eseguirlo su un processore CUDA e fare la stessa cosa, se possibile.

Quello che stai cercando sono linee di codice che hanno un'alta occupazione nello stack di chiamate, come mostrato dalla frazione di campioni di stack che le contengono. Questi sono i tuoi "colli di bottiglia". Non ci vuole un numero molto grande di campioni per individuarli.

+0

Hai ragione, questo è un grande IF. E una delle mie principali preoccupazioni è come determinare che tu abbia selezionato l'algoritmo corretto in primo luogo. Gli algoritmi corretti sulla CPU possono essere molto diversi dai corretti algoritmi sulla GPU. –

+0

@ John-Dibling: Beh, in tal caso vedrei come posso ottenere gli stackshots su un processore CUDA. Vorrei cacciare abbastanza duramente per un debugger che potesse fare un passo o mettere in pausa almeno un processore e mostrare il suo stato. Sono stato il codice di ottimizzazione, incorporato e non, per 30 anni, e questo è il metodo che uso. Gli unici profiler che possono avvicinarsi a stare in piedi sono quelli che prelevano i campioni e riassumono a livello di linea/istruzione. –