Domanda

Sono interessato a sapere se alcuni algoritmi comuni (ordinamento, ricerca, grafici, ecc.) sono stati portati su OpenCL (o in qualsiasi linguaggio GPU) e come le prestazioni si confrontano con lo stesso algoritmo eseguito dalla CPU. Sono particolarmente interessato ai risultati (numeri).

Grazie!

È stato utile?

Soluzione

Ci sono alcuni esempi di questo genere di cose sul sito Web di NVidia. Tieni presente che alcune cose come l'ordinamento richiedono algoritmi speciali per un parallelismo efficiente e potrebbero non essere altrettanto efficienti di un algoritmo non thread su un singolo core.

Altri suggerimenti

Le GPU sono hardware altamente specializzati progettati per svolgere un piccolo insieme di attività molto bene e altamente parallelizzate. Questo è fondamentalmente aritmetico (in particolare matematica a virgola mobile a precisione singola sebbene le GPU più recenti facciano abbastanza bene con doppia precisione). Come tali sono adatti solo a particolari algoritmi. Non sono sicuro che l'ordinamento rientri in quella categoria (almeno nel caso generale).

Esempi più comuni sono i prezzi degli strumenti finanziari, grandi quantità di matematica matriciale e persino sconfiggendo la crittografia (con forza bruta). Detto questo, ho trovato Ordinamento rapido di GPU parallele utilizzando un algoritmo ibrido .

Un altro esempio comunemente citato è che esegue SETI @ HOME su una GPU Nvidia ma sta confrontando le mele con arance. Le unità di lavoro per le GPU sono diverse (e altamente limitate) rispetto a ciò che fanno normalmente le CPU.

Dai un'occhiata a spinta :

  

Thrust è una libreria CUDA di parallelo   algoritmi con un'interfaccia   simile al modello standard C ++   Biblioteca (STL). La spinta fornisce a   interfaccia flessibile di alto livello per GPU   programmazione che migliora notevolmente   produttività degli sviluppatori.

ATTENZIONE, MOLTO PREVISTO di qualsiasi numero di prestazioni quotato per GPGPU. Molte persone amano pubblicare numeri davvero impressionanti che non prendono in considerazione il tempo di trasferimento necessario per recuperare i dati di input dalla CPU alla GPU e i dati di output, entrambi superando un collo di bottiglia PCIe.

Il ridimensionamento delle immagini deve essere comune su molti siti Web che accettano caricamenti di immagini.

Il ridimensionamento di un'immagine jpeg da 2600 x 2000 m 2 jp (a 512 x 512) ha richiesto 23,5 millisecondi in C # con opzioni di qualità assolutamente inferiore e campionamento più vicino. La funzione utilizzata era graphics.DrawImage () basata su uno. Anche l'utilizzo della CPU era% 21,5.

Ottenere " array di byte rgba " l'estrazione sul lato C # e l'invio alla GPU e il ridimensionamento in GPU e il recupero dei risultati in un'immagine hanno richiesto 6,3 millisecondi e l'utilizzo della CPU è stato del 12,7%. Ciò è stato fatto con una GPU% 55 più economica con solo 320 core.

Solo un moltiplicatore di accelerazione 3.73X.

Il fattore limitante qui era l'invio dei dati rgb estratti da 20 MB (jpeg è solo 2 MB!) alla GPU. Quella parte che richiedeva tempo era quasi il 90% del tempo totale, inclusa l'estrazione di array di byte lato C #! Quindi immagino che ci sarebbe una velocità circa 30X almeno se la parte di estrazione potesse essere eseguita anche in GPU.

30X non è male.

Quindi è possibile eseguire il pipeline del livello di estrazione con il livello di ridimensionamento per nascondere la latenza della copia della memoria per ottenere ancora più velocità! Potrebbe essere 40X-50X.

Quindi aumenta la qualità del campionamento (come bicubico invece del vicino più vicino), hai ancora più vantaggio sul lato GPU. L'aggiunta di un filtro gaussiano 5x5 ha aggiunto solo 0,77 millesimi. Inoltre, la CPU otterrebbe un tempo maggiore, soprattutto se i parametri gaussiani necessari sono diversi dall'implementazione di Net #.


Anche se non sei soddisfatto del rapporto di accelerazione, scaricando su GPU e avendo un "core gratuito" sulla CPU è ancora vantaggioso per inviare più lavoro a quel server.

Ora aggiungi il fatto dei livelli di consumo energetico della GPU (30W contro 125W in questo esempio), è molto più vantaggioso.


La CPU difficilmente potrebbe vincere in

 C[i]=A[i]+B[i]

benchmark quando entrambe le parti funzionano con codici ottimizzati e puoi ancora scaricare metà degli array su GPU e finire più velocemente usando CPU + GPU allo stesso tempo.


La GPU non è stata creata per lavori non uniformi. Le GPU hanno condotte profonde, quindi in piedi dopo uno stallo a causa della ramificazione, impiega troppo tempo. Anche l'hardware di tipo SIMD lo costringe a fare la stessa cosa su tutti i componenti di lavoro. Quando un workitem fa una cosa diversa rispetto al gruppo, perde traccia e aggiunge bolle nell'intera pipeline SIMD o semplicemente altri aspettano il punto di sincronizzazione. Pertanto, il bilanciamento influisce sia sulle aree profonde che su quelle ampie della pipeline e lo rende ancora più lento della CPU in condizioni perfettamente caotiche.

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