Ci sono dei vantaggi nell'usare la CPU anziché la GPU?


63

Ho studiato processori e schede grafiche e ho scoperto che le GPU sono molto più veloci delle CPU. Ho letto in questo articolo , una GPU Nvidia di 2 anni ha superato di 14 volte un processore Intel Core I7 da 3,2 GHz di 14 volte in determinate circostanze. Se le GPU sono così veloci, perché gli sviluppatori non le usano per tutte le funzioni di un gioco? È possibile per le GPU fare qualcosa di diverso dalla grafica?


17
Se sei in un gioco in cui stai scaricando tutto sulla GPU e la tua CPU non fa quasi nulla, puoi ottenere un aumento delle prestazioni rimettendo parte del carico sulla CPU.
Tetrad,

3
la tua GPU è forse migliore della tua CPU, ma non credo che la tua scheda video sia migliore della tua scheda madre (e non confronterò il sistema operativo con il driver lol)
e-MEE

27
GPU is faster than a CPUè un falso mito che molte persone sono portate a credere dopo aver visto benchmark basati su problemi che sono specificamente orientati per la GPU (questa classe di problemi è chiamata "problemi imbarazzanti paralleli"), vedi la mia risposta su questa domanda di SuperUser: Perché stiamo ancora usando CPU anziché GPU?
Lie Ryan,


5
Un vantaggio è che ogni computer ha una CPU :)
Tim Holt,

Risposte:


50

"Ho letto che le auto da F1 sono più veloci di quelle che guidiamo per strada ... perché allora le persone non usano le auto da F1?" Bene ... La risposta a questa domanda è semplice: le auto di F1 non possono rompersi o girare velocemente come la maggior parte delle auto (l'auto più lenta potrebbe battere una F1 in quel caso). Il caso delle GPU è molto simile, sono bravi a seguire una linea retta di elaborazione, ma non sono così bravi quando si tratta di scegliere percorsi di elaborazione diversi.

Un programma eseguito nella GPU ha senso quando deve essere eseguito più volte in parallelo, ad esempio quando devi fondere tutti i pixel della trama A con i pixel della trama B e metterli tutti nella trama C. Questa attività, quando eseguita in una CPU, verrebbe elaborata come questa:

for( int i =0; i< nPixelCount; i++ )
     TexC[i] = TexA[i] + TexB[i];

Questo è lento quando devi elaborare molti pixel, quindi la GPU invece di usare il codice sopra, usa solo il prossimo:

     TexC[i] = TexA[i] + TexB[i];

e quindi popola tutti i core con questo programma (essenzialmente copiando il programma sul core), assegnando un valore iper ciascuno. È allora che arriva la magia dalla GPU e fa sì che tutti i core eseguano il programma contemporaneamente , facendo molte operazioni molto più velocemente di quanto il programma della CPU lineare potrebbe fare.

Questo modo di lavorare è ok quando devi elaborare allo stesso modo molti piccoli input, ma è davvero male quando devi creare un programma che può avere una ramificazione condizionale. Quindi ora vediamo cosa fa la CPU quando si tratta di un controllo delle condizioni:

  • 1: eseguire il programma fino alla prima operazione logica
  • 2: valuta
  • 3: continua l'esecuzione dal risultato dell'indirizzo di memoria del confronto (come con un'istruzione asm JNZ)

Questo è molto veloce per la CPU come impostazione di un indice, ma per la GPU fare lo stesso, è molto più complicato. Poiché la potenza della GPU proviene dall'esecuzione della stessa istruzione contemporaneamente (sono core SIMD), devono essere sincronizzati per poter sfruttare l'architettura del chip. Dover preparare la GPU a gestire le filiali implica più o meno:

  • 1: crea una versione del programma che segua solo il ramo A, compila questo codice in tutti i core.
  • 2: eseguire il programma fino alla prima operazione logica
  • 3: Valuta tutti gli elementi
  • 4: Continua l'elaborazione di tutti gli elementi che seguono il ramo A, accoda tutti i processi che hanno scelto il percorso B (per il quale non esiste un programma nel core!). Ora tutti quei core che hanno scelto il percorso B saranno IDLE !! - il caso peggiore è l'esecuzione di un singolo core e tutti gli altri core che stanno solo aspettando.
  • 5: Al termine dell'elaborazione di tutti gli As, attivare la versione del programma B del ramo (copiandola dai buffer di memoria in una piccola memoria core).
  • 6: eseguire il ramo B.
  • 7: se necessario, fondere / unire entrambi i risultati.

Questo metodo può variare in base a molte cose (ad esempio alcune molto piccolele filiali sono in grado di funzionare senza la necessità di questa distinzione) ma ora puoi già capire perché la ramificazione sarebbe un problema. Le cache della GPU sono molto piccole che non puoi semplicemente eseguire un programma dalla VRAM in modo lineare, deve copiare piccoli blocchi di istruzioni sui core per essere eseguito e se hai rami abbastanza la tua GPU sarà per lo più bloccata rispetto all'esecuzione qualsiasi codice, il che non ha senso quando si esegue un programma che segue solo un ramo, come la maggior parte dei programmi, anche se in esecuzione su più thread. Rispetto all'esempio di F1, sarebbe come dover aprire i paracadute di frenata in ogni angolo, quindi uscire dall'auto per rimetterli dentro l'auto fino all'angolo successivo che si desidera girare di nuovo o trovare un semaforo rosso (angolo successivo più probabilmente).

Quindi, naturalmente, c'è il problema che altre architetture sono così brave nel compito di operazioni logiche, molto più economiche e più affidabili, standardizzate, meglio conosciute, efficienti dal punto di vista energetico, ecc. Le videocard più recenti non sono quasi compatibili con quelle precedenti senza emulazione software, usano istruzioni asm diverse tra loro anche se provenienti dallo stesso produttore e che per il momento la maggior parte delle applicazioni informatiche non richiedono questo tipo di architettura parallela e anche se ne hanno bisogno, possono utilizzare tramite API standard come OpenCL come menzionato da eBusiness, o attraverso le API grafiche. Probabilmente tra qualche decennio avremo GPU in grado di sostituire le CPU ma non credo che accadrà presto.

Raccomando la documentazione dell'APP AMD che spiega molto sulla loro architettura GPU e ho anche visto di quelli NVIDIA nei manuali CUDA, che mi hanno aiutato molto a comprenderlo. Ancora non capisco alcune cose e potrei sbagliarmi, probabilmente qualcuno che ne sa di più può confermare o smentire le mie affermazioni, il che sarebbe fantastico per tutti noi.


6
strana analogia ma è un buon punto the fastest isn't always the fastest.
Sdraiati Ryan il

1
Grazie! Penso che sia un argomento interessante perché lega molti concetti di programmazione del gioco al modo in cui funziona l'hardware, che è un po 'dimenticato nella terra dei linguaggi di alto livello di oggi. Ci sono alcune altre cose che vorrei aggiungere, ma scrivere la risposta ha richiesto già un po 'di tempo, quindi cercherò di aggiornarlo in seguito, come le funzionalità di "modalità protetta" delle CPU, la velocità del bus di memoria, ecc. Ma spero che questo chiarisca alcuni svantaggi tecnici dell'esecuzione di tutto nella GPU.
Pablo Ariel,

6
L'analogia sarebbe molto meglio se fosse accurata. Le vetture di F1 hanno incredibili capacità di frenata che consentono loro di mantenere un'alta velocità in una curva invece di iniziare a frenare con largo anticipo. Anche in curva ad alta velocità è migliore grazie a forti downforces, anche se il raggio di sterzata probabilmente non è eccezionale per i parcheggi. Motivi migliori potrebbero includere la mancanza di spazio di stivaggio, specchietto retrovisore, aria condizionata, controllo della velocità di crociera, protezione dagli elementi, sedili passeggeri, sospensioni e altezza libera dal suolo per gestire strade povere o varie altre cose comuni nei veicoli passeggeri.
GargantuChet,

5
@Pablo Ariel Sto rispondendo alla dichiarazione: "Le auto di F1 non possono rompersi o girare velocemente come la maggior parte delle auto". Suggerisci che le auto di F1 possano solo accelerare in linea retta e non sono molto buone in curva o durante la decelerazione. Ma le auto di F1 in realtà possono frenare molto più rapidamente della "maggior parte delle auto" e sono eccellenti in curva ad alta velocità.
GargantuChet,

4
L'analogia è più accurata se si pensa a Dragsters piuttosto che a macchine da Formula 1
Agustin Meriles,

32

Le GPU sono ottime attività parallele. Il che è fantastico ... se stai eseguendo attività parallele.

I giochi riguardano il tipo di applicazione meno parallelizzabile. Pensa al loop di gioco principale. L'intelligenza artificiale (supponiamo che il giocatore sia gestito come un caso speciale dell'IA) deve rispondere alle collisioni rilevate dalla fisica. Pertanto, deve essere eseguito successivamente. O almeno, la fisica ha bisogno di chiamare routine di intelligenza artificiale entro i limiti del sistema fisico (che generalmente non è una buona idea per molte ragioni). La grafica non può essere eseguita fino a quando non viene eseguita la fisica, poiché la fisica è ciò che aggiorna la posizione degli oggetti. Naturalmente, anche l'IA deve essere eseguita prima del rendering, poiché l'IA può generare nuovi oggetti. I suoni devono essere eseguiti dopo i controlli AI e del lettore

In generale, i giochi possono infilarsi in pochissimi modi. La grafica può essere scartata in un thread; il loop di gioco può raccogliere un sacco di dati nel thread grafico e dire: renderlo. Può eseguire alcune interpolazioni di base, in modo che il ciclo di gioco principale non debba essere sincronizzato con la grafica. Il suono è un altro thread; il loop del gioco dice "gioca a questo" e viene riprodotto.

Dopodiché, tutto inizia a diventare doloroso. Se disponi di algoritmi di pathing complessi (come per gli RTS), puoi threadarli. Il completamento degli algoritmi potrebbe richiedere alcuni frame, ma almeno saranno simultanei. Oltre a ciò, è piuttosto difficile.

Quindi stai guardando 4 thread: gioco, grafica, suono e possibilmente elaborazione AI a lungo termine. Non è molto. E questo non è quasi sufficiente per le GPU, che può avere letteralmente centinaia di discussioni in volo in una sola volta. Questo è ciò che offre alle GPU le loro prestazioni: essere in grado di utilizzare tutti quei thread contemporaneamente. E i giochi semplicemente non possono farlo.

Ora, forse potresti essere in grado di andare "largo" per alcune operazioni. Gli IA, ad esempio, sono generalmente indipendenti l'uno dall'altro. Quindi potresti elaborare diverse dozzine di IA contemporaneamente. Fino a quando non è necessario renderli dipendenti l'uno dall'altro. Allora sei nei guai. Gli oggetti fisici sono ugualmente indipendenti ... a meno che non ci sia un vincolo tra loro e / o si scontrino con qualcosa. Quindi diventano molto dipendenti.

Inoltre, c'è il fatto che la GPU semplicemente non ha accesso all'input dell'utente, che a quanto ho capito è un po 'importante per i giochi. Quindi dovrebbe essere fornito. Inoltre non ha accesso diretto ai file o alcun metodo reale di parlare con il sistema operativo; così di nuovo, ci dovrebbe essere un modo per fornire questo. Oh, e tutta quella elaborazione del suono? Le GPU non emettono suoni. Quindi quelli devono tornare alla CPU e poi al chip audio.

Oh, e la codifica per le GPU è terribile. È difficile ottenere il giusto, e ciò che è "giusto" per un'architettura GPU può essere molto, molto sbagliato per un altro. E questo non è nemmeno solo il passaggio da AMD a NVIDIA; potrebbe passare da una GeForce 250 a una GeForce 450. Questo è un cambiamento nell'architettura di base. E potrebbe facilmente far sì che il codice non funzioni correttamente. C ++ e anche C non sono ammessi; il meglio che ottieni è OpenCL, che è un po 'come la C ma senza alcune delizie. Come la ricorsione . Esatto: nessuna ricorsione sulle GPU.

Debug? Oh, spero che non ti piacciano le funzionalità di debug del tuo IDE, perché quelle sicuramente non saranno disponibili. Anche se stai usando GDB, bacia quell'addio. Dovrai ricorrere al printfdebug ... aspetta, non ci sono printfGPU. Quindi dovrai scrivere nelle posizioni di memoria e far rileggere il tuo programma di stub della CPU.

Esatto: debug manuale . Buona fortuna.

Inoltre, quelle utili librerie che usi in C / C ++? O forse sei più un tipo .NET, usa XNA e così via. O qualunque cosa. Non importa, dal momento che non è possibile utilizzare nessuno di essi sulla GPU. Devi codificare tutto da zero. E se hai già una base di codice esistente, difficile: è tempo di riscrivere tutto quel codice.

Quindi si È orribile da fare per qualsiasi tipo di gioco complesso. E non funzionerebbe nemmeno, perché i giochi non sono abbastanza paralleli per essere d'aiuto.


21

Perché non è così facile rispondere - è importante notare che le GPU sono processori specializzati che non sono realmente destinati all'uso generalizzato come una normale CPU. A causa di questa specializzazione, non sorprende che una GPU possa sovraperformare una CPU per le cose per le quali è stata appositamente progettata (e ottimizzata), ma ciò non significa necessariamente che possa sostituire la piena funzionalità e le prestazioni di una CPU generalizzata.

Sospetto che gli sviluppatori non lo facciano per una serie di motivi, tra cui:

  • Vogliono che la grafica sia la più veloce e la più alta qualità possibile e l'utilizzo di preziose risorse GPU potrebbe interferire con questo.

  • Potrebbe essere necessario scrivere un codice specifico per la GPU, e questo probabilmente introdurrà ulteriore complessità alla programmazione generale del gioco (o dell'applicazione) a portata di mano.

  • Una GPU normalmente non ha accesso a risorse come schede di rete, tastiere, mouse e joystick, quindi non è comunque possibile gestire ogni aspetto del gioco.

In risposta alla seconda parte della tua domanda: Sì, ci sono altri usi. Ad esempio, progetti come SETI @ Home (e probabilmente altri progetti BOINC) utilizzano GPU (come quelle di nVidia) per calcoli complessi ad alta velocità:

  Esegui SETI @ home sulla tua GPU NVIDIA
  http://setiathome.berkeley.edu/cuda.php

( Mi piace la tua domanda perché pone un'idea interessante. )


18

Le CPU sono più flessibili, generalmente è più facile programmarle, possono eseguire singoli thread molto più velocemente.

Mentre le GPU moderne possono essere programmate per risolvere praticamente qualsiasi attività, ottengono un vantaggio di velocità solo quando possono utilizzare la loro architettura parallela. Questo di solito è il caso di compiti "semplici" altamente ripetitivi. Gran parte del codice che scriviamo si sta ramificando in modo troppo imprevedibile per essere eseguito in modo efficiente su una GPU.

Inoltre, potresti finire per dedicare molto tempo all'ottimizzazione del codice per diversi chip grafici. Mentre OpenCL è disponibile per far funzionare lo stesso codice su molti chip grafici diversi, scambierai alcuni dei vantaggi di velocità per questo lusso.

Dal punto di vista del programmatore di giochi, in genere vorremmo che il nostro gioco funzionasse anche su computer con schede grafiche minori. Alcuni dei chip integrati non hanno la programmabilità richiesta, ma se lo fanno sono così lenti da non battere il processore con un margine molto grande, anche per il tipo di lavori in cui dovrebbero essere bravi. E ovviamente se avessi attinto a una GPU di fascia bassa per un gioco, avresti preso la potenza di elaborazione necessaria dal rendering grafico.

In effetti le prospettive sono fantastiche, ma quando si crea un gioco piuttosto che decifrare le password, i problemi pratici nella maggior parte dei casi superano i benefici.


6

Le GPU sono molto difficili da programmare. Dovresti cercare come ordinare un elenco su una GPU . Molte tesi hanno cercato di farlo.

Usare una CPU con un thread è facile, usare multi-thread è più difficile, usare molti computer con libreria parallela poiché PVM o MPI è difficile e usare una GPU è la più difficile.


4

Oltre a ciò che Randolf Richardson ha risposto, ci sono alcune funzionalità che i processori GPU non possono gestire da soli. Ad esempio, alcuni dei comandi di gestione della memoria grafica vengono elaborati dalla CPU poiché la GPU non è in grado di gestirli.

E c'è un'altra grande ragione, la GPU è progettata per calcoli multithread. Ciò significa che i produttori di GPU possono facilmente aggiungere core ogni volta che vogliono aumentare la potenza computazionale. Ma ci sono molti compiti che non possono essere suddivisi in piccoli problemi come il calcolo dell'ennesimo numero della serie Fibonacci . In queste situazioni la CPU è molto più veloce poiché è più ottimizzata per le attività a thread singolo.


4

Ci sono molte risposte che suggeriscono che le GPU sono solo più veloci perché gestiscono attività in parallelo. Questo sta esagerando un po 'il problema. Le GPU possono essere più efficienti per altri motivi, come la possibilità di avere un accesso alla memoria più restrittivo, il fatto di non dover supportare più tipi di dati, la possibilità di avere un set di istruzioni più efficiente, ecc. Le GPU iniziali potevano ancora disegnare solo 1 pixel a una volta, ma era il fatto che potevano fare 1 ogni ciclo che era importante.

La vera differenza è perché sono 2 diversi tipi di macchine che sono personalizzate per funzionare bene su diverse categorie di attività che sembrano simili ma in realtà abbastanza diverse. È come confrontare un aeroplano con un'auto. L'aereo ha una velocità massima molto più alta ma ha più restrizioni su come può essere utilizzato. Nelle occasioni in cui puoi fare lo stesso viaggio con entrambi i tipi, l'aereo sembra superiore.


L'analogia sull'aereo è molto buona (+1), ma per quanto riguarda le CPU che supportano diversi tipi di dati che in realtà è più un concetto di linguaggio di livello superiore poiché le CPU (almeno nello spazio Intel) tendono a gestire solo dati in forme molto semplici (ad es. bit, byte, parole, password, ecc.). Ci sono alcune istruzioni a ciclo stretto per scansionare o copiare i dati che terminano con un byte zero, ma i dati in questi casi non sono realmente riconosciuti dalla CPU come un tipo particolare (oltre ad essere un blocco di dati con terminazione zero nel contesto di questi loop).
Randolf Richardson,

@Randolf: le CPU hanno istruzioni e registri diversi che si occupano di diversi tipi di dati di basso livello (es. Con segno rispetto a non firmato, integrale contro virgola mobile). Questo è il caso dell'8086 e delle architetture più moderne, e non è completamente gratuito.
Kylotan,

Sono sicuro che fanno ancora molta elaborazione lineare nell'architettura sottostante. Dal punto di vista della programmazione sono necessarie solo istruzioni per la GPU ma i core non vengono eseguiti esattamente in parallelo a causa della loro dipendenza da altri hardware che non sono paralleli come la lettura dalla memoria, probabilmente la GPU può fornire dati a un singolo core in un tempo.
Pablo Ariel,

3

Gli sviluppatori non utilizzano le GPU per tutte le funzioni Sono bravi a. Usano le CPU per tutte le funzioni in cui sono bravi. Cosa ti fa pensare che non lo facciano?

Le GPU sono brave in compiti che possono essere paralizzati in modo massiccio e richiedono enormi quantità di calcolo con requisiti di memoria bassi o elevata correlazione temporale con solo piccole quantità di processo decisionale. Ciò include il rendering di immagini, simulazioni fisiche (particelle, collisione, stoffa, acqua, riflessione) e così via. Questo è esattamente ciò per cui i giochi moderni usano la GPU.

Le CPU sono brave in compiti che non si parallelizzano bene e richiedono enormi quantità di decisioni. Possono tollerare requisiti di memoria elevati anche con una moderata correlazione temporale. Ciò include intelligenza artificiale, interfaccia utente, I / O del disco e della rete e così via. Questo è esattamente ciò per cui i giochi moderni usano la CPU.


1

Il readback è un altro motivo che mi viene in mente di preferire di tanto in tanto la CPU. Non in termini di larghezza di banda (poiché la larghezza di banda GPU-> CPU non è un problema sull'hardware moderno) ma in termini di blocco della pipeline. Se hai bisogno di recuperare i risultati da un calcolo e fare qualcosa di interessante o utile con loro, usare la GPU non è una scelta saggia (nel caso generale - ci saranno casi speciali in cui può rimanere appropriato) poiché la rilettura richiederà sempre la GPU per interrompere qualunque cosa stia facendo, svuotare tutti i comandi in sospeso e attendere il completamento del readback. Questo può uccidere le prestazioni nella misura in cui non solo cancella i vantaggi dell'utilizzo della GPU, ma può effettivamente essere notevolmente più lento.


0

Questo è un vecchio thread, ma questo articolo pubblicato di recente potrebbe rispondere a questa domanda. Questo documento, pubblicato su ACM Computing Surveys 2015, mostra che ciascuna CPU e GPU hanno i loro vantaggi unici e quindi, questo documento è un motivo per passare dal paradigma "CPU vs GPU" al paradigma "CPU-GPU collaborative computing".

Un sondaggio sulle tecniche di elaborazione eterogenee CPU-GPU

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.