2013-09-01 20 views
5

Sto cercando la funzione multiscan/multi prefix-sum (molte righe in un kernel esecuzione) per il mio progetto in CUDA.funzione di somma/scansione del prefisso ad alte prestazioni in CUDA, alla ricerca di spinte, alterazione della libreria cuDPP

Ho provato quello della libreria Thrust ma è troppo lento. Inoltre, si verifica un arresto anomalo dopo essere stato compilato con i flag di debug nvcc (-g -G).

Dopo il mio fallimento con Thrust mi sono concentrato sulla libreria cuDPP che faceva parte del toolkit CUDA. Le prestazioni cuDPP sono davvero buone, ma la libreria non è aggiornata con l'ultimo cuda 5.5 e ci sono alcuni problemi di violazione della memoria globale nella funzione cudppMultiScan() durante il debug con il controllo della memoria. (cuda 5.5, nsight 3.1, studio visivo 2010, gtx 260 cc 1.3)

Qualcuno ha idea di cosa utilizzare al posto di queste due librerie?

R.

+0

Hai guardato [ArrayFire] (http://accelereyes.com/arrayfire), su cui lavoriamo su AccelerEyes? – arrayfire

+0

no, non l'ho visto prima, sembra piuttosto interessante! Grazie! :) e le sue prestazioni? È più una libreria orientata alla produttività o alla produttività? – user1946472

+0

Se si desidera utilizzare Thrust per eseguire la scansione delle righe di una matrice, non chiamare ripetutamente "inclusive_scan". Assegna ad ogni riga un indice e usa 'inclusive_scan_by_key'. Puoi adattare questo [esempio] (https://github.com/thrust/thrust/blob/master/examples/sum_rows.cu). –

risposta

2

Queste librerie, in particolare di spinta, cercare di essere il più generico possibile e l'ottimizzazione spesso richiede specializzazione: per esempio una specializzazione di un algoritmo in grado di utilizzare la memoria condivisa per i tipi fondamentali (come int o float), ma la versione generica non può. Succede che per una situazione particolare manca una specializzazione!

È consigliabile utilizzare queste librerie generiche ben collaudate il più possibile, ma a volte, per alcune sezioni di prestazioni critiche, la propria implementazione è un'opzione da considerare.

Nella propria situazione si desiderano molte scansioni in parallelo per righe diverse. Una buona implementazione non eseguiva la scansione separatamente per righe diverse: avrebbe la stessa chiamata del kernel in esecuzione simultaneamente per tutti gli elementi di tutte le righe. A seconda dell'indice, un thread può sapere quale riga sta elaborando e ignorerà tutti i dati fuori dalla riga.

Tale specializzazione richiede un funtore che restituisca un valore assorbente che impedisca la miscelazione delle file. Tuttavia, la tua attenta implementazione sarebbe probabilmente più veloce.

2

Per scrivere il proprio scansione prefisso, si può fare riferimento a

  1. L'esempio scansione del CUDA SDK;
  2. Capitolo 13 di N. Wilt, "Manuale CUDA";
  3. Capitolo 6 di S. Cook, "Programmazione CUDA, Guida per lo sviluppatore per il calcolo parallelo con GPU";
  4. Parallel Prefix Sum (Scan) with CUDA.

Per fare più prefisso a somma è possibile avviare molte volte lo stesso kernel (come suggerito da a.lasram) o cercare di ottenere cuncurrency da ruscelli CUDA, anche se non so che questo funzionerà in modo efficace per la scheda .

+0

L'utilizzo degli stream è un'ottima idea, ma penso che sia ancora meglio lanciare un singolo kernel in cui ogni thread "stringe" il calcolo in una riga selezionata –

+0

Ho 231 righe di 1424 float quindi l'esecuzione di ogni riga in un kernel separato dà troppo tempo sovraccarico causato da cudalaunch. cuDPP fa questo lavoro in circa 0,11 ms sulla mia macchina (gtx260) che per me è un risultato eccellente! In caso di prestazioni, cuDPP lib è perfetto. Per ora proverò la libreria arrayFire suggerita da @accelereyes. La ringrazio per la risposta. – user1946472