2011-08-17 17 views
16

Conosco molti esempi quando GPU è molto più veloce della CPU. Ma esistono algoritmi (problemi) che sono molto difficili da parallelizzare. Potresti fornirmi alcuni esempi o test quando la CPU può superare la GPU?cpu vs gpu - quando cpu è migliore

Modifica:

Grazie per i suggerimenti! Possiamo fare un confronto tra le cpu e le gpu più popolari e più recenti, ad esempio Core i5 2500k vs GeForce GTX 560 Ti.

Mi chiedo come confrontare il modello SIMD tra di loro. Ad esempio: Cuda chiama un modello SIMD più precisamente SIMT. Ma SIMT dovrebbe essere paragonato al multhitreading su CPU che sta distribuendo thread (task) tra i core MIMD (Core i5 2500k fornisce come 4 core MIMD). D'altra parte ognuno di questi core MIMD può implementare il modello SIMD, ma questo è qualcosa di diverso dal SIMT e non so come confrontarli. Infine un'architettura fermi con esecuzione concomitante del kernel potrebbe essere considerata come core MIMD con SIMT.

+1

Si prega di leggere [questo post del blog] (http://blog.stackoverflow.com/2011/08/gorilla-vs-shark/) prima di fare altre domande come questa su StackOverflow. – talonmies

+1

@talonmies: Non sono d'accordo: questa è una domanda molto specifica con una risposta molto specifica. L'unico punto contro di esso è che è * probabilmente * un duplicato di qualche altra domanda. –

+1

possibile duplicato di [GPGPU vs Multicore?] (Http://stackoverflow.com/questions/5919172/gpgpu-vs-multicore) –

risposta

15

Sulla base della mia esperienza, riassumerò le principali differenze in termini di prestazioni tra programmi paralleli in CPU e GPU. Fidati di me, un confronto può essere cambiato di generazione in generazione. Quindi indicherò cosa è buono ed è dannoso per CPU e GPU. Ovviamente, se si esegue un programma estremo, cioè con lati negativi o positivi, verrà eseguito in modo decisamente più rapido su una piattaforma.. Ma una miscela di questi richiede un ragionamento molto complicato.

livello di programma Host

Una differenza fondamentale è il costo di trasferimento di memoria. I dispositivi GPU richiedono alcuni trasferimenti di memoria. Questo costo non è banale in alcuni casi, ad esempio quando si devono trasferire frequentemente grandi array. Nella mia esperienza, questo costo può essere ridotto al minimo, ma spingere la maggior parte del codice host al codice del dispositivo. Gli unici casi che puoi fare sono quando devi interagire con il sistema operativo host in programma, come ad esempio l'output per il monitoraggio.

livello di programma dispositivo

Veniamo ora a vedere un quadro complesso che non è stato ancora completamente rivelato. Quello che voglio dire è che ci sono molte scene misteriose in GPU che non sono state divulgate. Ma ancora, abbiamo un sacco di distinguere CPU e GPU (codice del kernel) in termini di prestazioni.

Ci sono alcuni fattori che ho notato che contribuiscono notevolmente alla differenza.

  • distribuzione del carico di lavoro

GPU, che consistono di molte unità di esecuzione, sono progettati per gestire programmi paralleli. Se hai poco lavoro, pronuncia alcune attività sequenziali e metti queste attività su una GPU, solo alcune di quelle molte unità di esecuzione sono occupate, quindi saranno più lente della CPU. Perché le CPU sono, in altre parole, meglio gestire le attività brevi e sequenziali. La ragione è semplice, le CPU sono molto più complicate e in grado di sfruttare il parallelismo a livello di istruzioni, mentre le GPU sfruttano il parallelismo a livello di thread. Bene, ho sentito che NVIDIA GF104 può fare Superscalar, ma non ho avuto alcuna possibilità di sperimentarlo.

Vale la pena notare che, nelle GPU, il carico di lavoro è diviso in piccoli blocchi (o gruppi di lavoro in OpenCL) e i blocchi sono disposti in blocchi, ognuno dei quali viene eseguito in un processore Streaming (sto usando le terminologie di NVIDIA) . Ma nelle CPU, questi blocchi vengono eseguiti in modo sequenziale: non riesco a pensare a nient'altro che a un singolo ciclo.

Pertanto, per i programmi che hanno un numero ridotto di blocchi, sarà probabile che l'esecuzione di venga eseguita più rapidamente sulle CPU.

  • istruzioni di controllo di flusso

rami sono cose cattive per GPU, sempre. Si prega di tenere presente che le GPU preferiscono le cose uguali. Blocchi uguali, fili uguali all'interno di un blocco e fili uguali all'interno di un ordito. Ma cosa conta di più?

      ***Branch divergences.*** 

I programmatori CUDA/OpenCL odiano le divergenze delle filiali. Poiché tutti i thread sono in qualche modo suddivisi in serie di 32 thread, chiamati warp, e tutti i thread all'interno di un warp vengono eseguiti in sequenza, una divergenza di branch causerà la serializzazione di alcuni thread nel warp. Pertanto, il tempo di esecuzione dell'ordito sarà di conseguenza moltiplicato.

A differenza delle GPU, ogni core nelle CPU può seguire il proprio percorso. Inoltre, le filiali possono essere eseguite in modo efficiente perché le CPU hanno una previsione di filiale.

Pertanto, i programmi con più divergenze di ordito sono probabile che l'esecuzione di avvenga più rapidamente sulle CPU.

  • istruzioni di accesso alla memoria

Questo in realtà è abbastanza complicato così facciamo breve.

Ricordare che gli accessi alla memoria globale hanno una latenza molto elevata (400-800 cicli). Quindi, nelle vecchie generazioni di GPU, la condivisione degli accessi alla memoria era una questione cruciale. Ora la tua GTX560 (Fermi) ha più 2 livelli di cache. In molti casi, il costo di accesso alla memoria globale può essere ridotto. Tuttavia, le cache nelle CPU e nelle GPU sono diverse, quindi anche i loro effetti sono diversi.

Ciò che posso dire è che dipende in realtà molto dal modello di accesso alla memoria, dal modello del codice del kernel (come gli accessi alla memoria sono interlacciati con il calcolo, i tipi di operazioni, ecc.) Per sapere se si corre più velocemente sulle GPU o CPU.

Ma in qualche modo ci si può aspettare un numero enorme di errori di cache (in GPU) ha un effetto molto negativo sulle GPU (quanto male? Dipende dal codice).

Inoltre, la memoria condivisa è una caratteristica importante delle GPU. L'accesso alla memoria condivisa è veloce quanto l'accesso alla cache della GPU L1. Quindi i kernel che fanno uso della memoria condivisa avranno un grande vantaggio.

Alcuni altri fattori che non ho davvero menzionati ma quelli possono avere grande impatto sulle prestazioni, in molti casi, come i conflitti bancari, dimensione della transazione di memoria, doppia GPU ...

Problemi correlati