2009-02-21 8 views
22

Non so come i giochi commerciali funzionino molto all'interno, ma i giochi open source che ho incontrato non sembrano essere molto coinvolti nel threading. Lo stesso vale per la maggior parte delle altre applicazioni desktop, in genere si utilizzano due o tre thread (ad esempio, la logica del programma e gli aggiornamenti della GUI).Perché i programmi di grandi dimensioni (come i giochi) utilizzano un sacco di thread diversi?

Perché i giochi non hanno molti thread? Es. Fili separati per fisica, suono, grafica, intelligenza artificiale ecc.?

+2

Il parallelismo è difficile. Non solo "wow, questo è difficile", ma "teoricamente, molti problemi non sono parallelizzabili". –

risposta

14

Molti giochi in questi giorni utilizzano i sistemi "task" o "job" per l'elaborazione parallela. Cioè, il gioco genera un numero fisso di thread di lavoro che vengono utilizzati per più attività. Il lavoro viene diviso in piccoli pezzi e accodato, quindi inviato per essere elaborato dai thread di lavoro man mano che diventano disponibili.

Questo sta diventando particolarmente comune sulle console. La PS3 si basa sull'architettura della cella, quindi è necessario utilizzare l'elaborazione parallela per ottenere le migliori prestazioni dal sistema. Xbox 360 è in grado di emulare una configurazione di attività/lavoro progettata per PS3 poiché ha più core. Probabilmente per la maggior parte dei giochi è probabile che gran parte della progettazione del sistema sia condivisa tra le basi di codice 360, PS3 e PC, quindi il PC utilizza molto probabilmente lo stesso tipo di tattica.

Mentre è difficile scrivere threadsafe codice, come molte delle altre risposte indicano, penso che ci sono alcune altre ragioni per le cose che stai vedendo:

  • In primo luogo, molti giochi open source sono alcuni anni. Soprattutto con questa generazione di console, la programmazione parallela sta diventando popolare e persino necessaria come menzionato sopra.
  • Secondo, pochissimi progetti open source sembrano preoccupati di ottenere le massime prestazioni possibili. Come ha sottolineato John Carmack nel progetto Utah GLX, il codice altamente ottimizzato è spesso più difficile da mantenere rispetto al codice non ottimizzato, quindi quest'ultimo sarebbe generalmente preferito nei contesti open source.
  • In terzo luogo, non prenderei un piccolo numero di thread creati da un gioco per significare che non sta utilizzando bene i lavori paralleli.
15

Il motivo principale è che, per quanto elegante possa sembrare, l'utilizzo di più thread in un programma complicato come un gioco 3D è davvero, davvero, davvero difficile. Inoltre, prima dell'introduzione abbastanza recente di sistemi multi-core a basso costo, l'utilizzo di più thread non offriva molti incentivi alle prestazioni.

23

Non conosco i giochi che hai giocato, ma molti giochi eseguono il suono su un thread separato. Codice di rete, almeno i listener di socket vengono eseguiti su un thread separato.

Tuttavia, il resto del motore di gioco generalmente viene eseguito in un singolo thread. Ci sono ragioni per questo. Ad esempio, la maggior parte dell'elaborazione di un gioco esegue una singola catena di dipendenze. La grafica dipende dallo stato del motore fisico così come l'intelligenza artificiale. Progettare per più thread significa che devi avere una latenza dei frame tra i vari sottosistemi per la concorrenza. Ottieni tempi di risposta più rapidi e giochi più nitidi se questi sottosistemi sono calcolati linearmente per ogni fotogramma. La parte del gioco che beneficia maggiormente della parallelizzazione è naturalmente il sottosistema di rendering che viene scaricato in schede di accelerazione grafica altamente parallele.

0

Ci sono molti problemi con condizioni di gara e blocco dei dati quando si utilizzano molti thread. Poiché le diverse parti dei giochi sono abbastanza dipendenti l'una dall'altra, non ha molto senso fare tutto il necessario per l'utilizzo di molti thread.

1

Stavo per pubblicare la stessa cosa di William, ma mi piacerebbe approfondire un po '. È molto difficile scrivere codice ottimale per il futuro. Data la scelta tra scrivere qualcosa che si ridurrà all'hardware che non hai vs scrivere qualcosa che funzioni sull'hardware che hai, la maggior parte delle persone sceglierà di farlo. Dal momento che il paradigma single-core è stato con noi per così tanto tempo, la maggior parte del codice che è stato scritto (specialmente per i giochi in cui vi è un'estrema pressione per farlo uscire) non è una prova futura.

x86 è stato molto gentile con i programmatori di giochi, dal momento che non abbiamo dovuto pensare alle ramificazioni delle piattaforme hardware meno tolleranti.

0

È molto difficile utilizzare i thread senza problemi e la maggior parte delle API della GUI si basano comunque sulla codifica basata sugli eventi. I thread impongono l'uso di meccanismi di blocco che aggiungono un ritardo al codice, e spesso tale ritardo è imprevedibile a seconda di chi detiene attualmente il blocco.

Sembra ragionevole per me avere un singolo (o forse pochi) thread che gestiscono le cose in un modo guidato dagli eventi piuttosto che centinaia di thread che causano tutti bug strani e irripetibili.

1

Oltre alle sfide tecniche di programmazione per più core, i giochi commerciali devono funzionare bene su sistemi di fascia bassa senza core multipli per fare soldi.

Ora che i processori multi-core sono usciti da un po 'di tempo e le principali console di gioco hanno più core, è solo una questione di tempo prima che il dual core si presenti nell'elenco dei requisiti minimi di sistema per i giochi per PC.

Ecco un collegamento a an interview with Orion Granatir da Intel, dove sta parlando di ottenere sviluppatori di giochi per sfruttare il multi-threading.

1

Il fatto che tutti qui affermino correttamente che il multithreading è difficile è molto triste. Abbiamo un disperato bisogno di rendere i sistemi di concorrenza facili.

Personalmente penso che avremo bisogno di un cambio di paradigma e di nuovi strumenti.

+1

sfortunatamente, questo è il modo in cui è. Gli strumenti non renderanno i thread più facili (ne abbiamo già alcuni, ad esempio, openmp o TBB). Il problema è semplicemente difficile. È possibile che otterremo strumenti migliori, ma appariranno a costo di prestazioni concorrenti al fine di far funzionare correttamente le app. – gbjbaanb

+0

shift di paradigma, quindi strumenti;) – Pyrolistical

15

È necessario pensare, quali sono i vantaggi effettivi dei thread? Ricorda che su una macchina single core, i thread non consentono effettivamente l'esecuzione simultanea, solo l'impressione di essa. Dietro le quinte, la CPU cambia il contesto tra i diversi thread, facendo un piccolo lavoro ogni volta. Pertanto, se ho diverse attività che non comportano l'attesa, eseguirle contemporaneamente (su un singolo core) non saranno più veloci di eseguirle linearmente. In effetti, sarà più lento, a causa del sovraccarico aggiunto della frequente commutazione di contesto.

Se è questo il caso, perché usare mai i thread su un singolo core? Innanzitutto, perché a volte le attività possono comportare lunghi periodi di attesa su alcune risorse esterne, come un disco o un altro dispositivo hardware, per essere disponibili. Mentre l'attività è in una fase di attesa, il threading consente ad altre attività di continuare, utilizzando in tal modo il tempo della CPU più efficiente.

In secondo luogo, le attività possono avere una scadenza di qualche tipo in cui completare, in particolare se rispondono a un evento. L'esempio classico è l'interfaccia utente di un'applicazione. Il computer dovrebbe rispondere agli eventi di azione dell'utente il più rapidamente possibile, anche se è occupato ad eseguire altre attività di lunga durata, altrimenti l'utente sarà agitato e potrebbe credere che l'applicazione si sia arrestata in modo anomalo. La filettatura consente che ciò accada.

Per quanto riguarda i giochi, non sono un programmatore di giochi, ma la mia comprensione della situazione è questa: i giochi 3D creano un modello programmatico del mondo di gioco; giocatori, nemici, oggetti, terreno, ecc. Questo mondo di gioco viene aggiornato in passaggi discreti, in base alla quantità di tempo trascorso dall'aggiornamento precedente. Quindi, se è passato 1ms dall'ultima volta del ciclo di gioco, la posizione di un oggetto viene aggiornata usando la sua velocità e il tempo trascorso per determinare il delta (ovviamente la fisica è un po 'più complicata di così, ma ottieni il idea). Altri fattori come l'intelligenza artificiale e i tasti di inserimento possono anche contribuire all'aggiornamento. Quando tutto è finito, il mondo di gioco aggiornato viene reso come un nuovo frame e il processo ricomincia. Questo processo di solito si verifica molte volte al secondo.

Quando pensiamo al circuito di gioco in questo modo, possiamo vedere che il motore sta infatti raggiungendo un obiettivo molto simile a quello del threading. Ha un numero di attività di lunga durata (aggiornamento della fisica del mondo, gestione dell'input dell'utente, ecc.) E dà l'impressione che stiano succedendo contemporaneamente suddividendoli in piccoli pezzi di lavoro e intrecciando questi pezzi, ma invece di fare affidamento su la CPU o il sistema operativo per gestire il tempo speso su ciascuno, lo fa da solo. Ciò significa che può mantenere sincronizzati tutti i diversi compiti ed evitare le complessità che derivano dal threading reale: lock, pre-emption, codice di rientro, ecc. Non c'è nessuna implicazione di prestazioni in questo approccio, perché, come abbiamo detto, la macchina single core può solo eseguire il codice in modo lineare in ogni caso.

Le cose cambiano quando si dispone di un sistema multi-core. Ora, i compiti possono essere eseguiti in modo sincrono contemporaneamente e potrebbe esserci un vantaggio nell'usare il threading per gestire diverse parti degli aggiornamenti del mondo di gioco, a patto che possiamo riuscire a sincronizzare i risultati per rendere i frame coerenti. Ci aspetteremmo quindi, che con l'avvento dei sistemi multi-core, gli sviluppatori di giochi dovrebbero lavorare su questo. E così risulta, lo sono. Valve, i creatori di Half Life, ha recentemente introdotto il supporto multiprocessore nel suo Source Engine, e immagino che molti altri sviluppatori di motori stiano seguendo la stessa cosa.

Bene, questo si è rivelato un po 'più lungo di quanto mi aspettassi. Non sono un esperto di threading o giochi, ma spero di non aver commesso errori particolarmente evidenti.Se sono sicuro che le persone mi correggeranno :)

+2

In realtà, anche i thread di una singola core machine possono avere un miglioramento delle prestazioni. Alcuni switch di macchine sostituiranno il thread in esecuzione a causa di blocchi di memoria. Se ricordo bene, l'HyperThreading di Intel fa qualcosa di simile. –

+0

+1 per la risposta dettagliata –

+0

Vorrei anche specificare che quando si usano i thread non si controlla effettivamente la loro programmazione con precisione. gli algoritmi di pianificazione sono progettati dal sistema operativo, non dallo sviluppo del gioco. Quindi se devi gestire le attività in un ordine rigoroso è (almeno) più facile farlo in un singolo thread. –

1

I fili sono morti, piccola.

Realisticamente, nello sviluppo del gioco, i thread non vanno oltre lo scaricamento di attività molto dedicate come il networking e il caricamento. I sistemi di lavoro sembrano essere l'unica soluzione, dato che 8 sistemi di CPU stanno diventando più comuni anche sui PC. E puoi praticamente garantire che i futuri sistemi super-multicore come Intel Larrabee saranno basati sul sistema di lavoro.

Questa è stata una realizzazione un po 'dolorosa per i progetti PlayStation3 e XBOX360, e ora sembra che anche Apple abbia fatto un salto nel loro "rivoluzionario" sistema Grand Central Dispatch in Snow Leopard.

I thread hanno il loro posto, ma l'ingenua promessa di "mettere tutto in un thread e tutto andrà più veloce" semplicemente non funziona nella pratica.

+0

... I thread sono parte integrante di ciò di cui stai parlando. È appena sotto un ulteriore livello di astrazione. – colithium

Problemi correlati