Quando un motore per attività parallele diventa una buona soluzione?


8

Sono spesso tentato di interrompere il gioco a cui sto lavorando per provare un'architettura basata su compiti paralleli, ma questo non sembra un grande requisito per il mio progetto, quindi per il momento lo evito. Ho intenzione di provarlo prima in un progetto di giocattolo, per "giocare con il concetto".

Ora, quello che sto chiedendo è che molti giochi (non AAA) non richiedono prestazioni davvero elevate, sembra che usare un motore basato su attività non valga la pena preoccuparsi fino a ... quali casi?

Al momento, sto solo supponendo che sia necessario quando devi davvero sfruttare le massime prestazioni dell'hardware (multi-core). Esistono altri casi in cui è una buona idea utilizzare un motore basato su attività? O forse, per i nuovi progetti, è sempre bene iniziare con un motore basato su attività?

Risposte:


7

Il threading viene utilizzato in due situazioni:

  1. Quando hai un lavoro pesante da fare ma hai bisogno di mantenere la reattività dell'utente.
  2. Quando hai bisogno della potenza di più di un core di elaborazione sulla tua piattaforma preferita / requisiti minimi.

Se puoi ragionevolmente aspettarti che una o entrambe queste cose siano necessarie, allora provaci. Altrimenti no. Naturalmente, nessuno ti impedirà di intrattenere il thread per divertimento perché puoi, o di curiosare e investigarlo, ma in termini di threadng per i vantaggi di ottenere effettivamente un'applicazione multi-thread, i due casi d'uso sopra sono praticamente.


2
+1 per la reattività: uno dei requisiti per il mio progetto principale è di non avere schermate di caricamento, esperienza continua per la massima immersione. È un buon punto.
Klaim

1
+1 esattamente perché ho usato più thread in un gioco puzzle: lavoro pesante (controllo di milioni di combinazioni) senza congelare l'interfaccia utente.
ashes999,

"nessuna schermata di caricamento, esperienza continua" - dovrai costruire tutta la tua architettura attorno a questa idea, è una pausa dal design "carica un livello e gioca in esso, quindi carica un altro livello" utilizzato dalla maggior parte dei piccoli motori.
Patrick Hughes,

14

Se il tuo gioco richiederà un utilizzo intensivo dell'hardware in remoto, avrai bisogno di thread per far fronte a tutto l'hardware moderno; le future CPU in uscita nel prossimo anno o due stanno iniziando a rendere 4 core il minimo e fino a 16 core comuni per i mercati degli appassionati / delle prestazioni. Se stai eseguendo un multithreading, esegui sicuramente un'architettura orientata alle attività poiché qualsiasi altro modello di threading è intrinsecamente rotto per i motori di gioco lungimiranti.

Ora tieni presente che per "compiti" intendo "lavori" e non "thread separati per diversi sottosistemi di motori". Non vuoi assolutamente fare qualcosa come avere un thread grafico, un thread di fisica, un thread di AI, ecc. Che non si ridimensiona oltre una manciata di core e in realtà non ti procura alcun vero parallelismo. La fisica non dovrebbe eseguire più di un aggiornamento per ogni aggiornamento AI (vuoi che la tua IA sia in grado di reagire agli eventi di fisica) e la grafica non ha quasi nulla di nuovo da visualizzare se la fisica non ha funzionato, quindi ogni sottosistema funziona naturalmente in sequenza ordine. Tu non

Quello che vuoi è fare è questo. Crea un rocchetto di filo. Esegui il tuo loop di gioco con la classica sequenza di aggiornamenti del sottosistema. Tuttavia, per ciascun sottosistema, separare il carico di lavoro in lotti separabili distinti e distribuirli al pool di thread. Attendere il completamento di tutti i processi prima di eseguire il successivo stato del ciclo di aggiornamento del gioco. Alcuni sottosistemi possono avere più sottostadi; ad esempio, la grafica può emettere una serie di lavori per l'abbattimento e quindi una seconda serie di lavori per la creazione della coda di rendering. Questo approccio evita il problema di sincronizzazione del primo approccio, si ridimensiona a un numero molto maggiore di core ed è francamente più semplice da programmare, eseguire il debug e mantenere.


Grazie per i consigli su come costruire questo tipo di motore, ma sono già ben documentato, quindi non era necessario. È più la domanda "quando ne vale la pena" che faccio. Penso che sia ancora una buona cosa indicare quelle informazioni per coloro che non sanno, quindi non rimuoverle :)
Klaim

Sembra molto ragionevole
Den,

Proprio come Apple, una volta abituati ai lavori non si può tornare indietro =) Questo è un buon suggerimento di architettura per qualsiasi nuovo motore.
Patrick Hughes,

@SeanMiddleditch Non stai semplicemente cambiando la granularità del threading in quel modo? Invece di un solo thread per sistema (che non è così scalabile, alcuni sistemi hanno molta più fame di energia di altri e ci possono essere anche molti più sistemi che core disponibili) stai facendo potenzialmente più thread per sistema. Quindi stai perfezionando la granularità dei dati su cui ogni thread agisce. Non sono sicuro di come andrà a finire, ma non ho niente di meglio da aggiungere. Hai ancora questa opinione dopo 7 anni? Grazie.
Nikos,

1
@ Nik-Lz: no, perché "più thread per sistema" implica che tu sappia quale dovrebbe essere il thread per sistema. Dovresti avere 2 thread per il rendering e 3 per la fisica? Quanti per l'IA? Tutto ciò non dipenderebbe dalla scena specifica e anche da dove sta il giocatore e cosa sta succedendo nel momento? Un sistema di lavoro si adatta facilmente in modo dinamico alle esigenze immediate piuttosto che eseguire il binning di un intero thread in un sottosistema che potrebbe non averne bisogno in questo momento.
Sean Middleditch,

0

ci sono due usi nel multithreading, uno è quello di migliorare le prestazioni del programma e l'altro è quello di consentire l'esecuzione del programma quando è in corso un processo di grandi dimensioni. ad esempio, quando si sta tentando di caricare alcuni dati, è fastidioso se il programma si blocca, quindi è possibile utilizzare un altro thread per il caricamento e mantenere il thread principale libero per continuare il ciclo principale. migliorare le prestazioni usando i thread è invece molto difficile. poiché di solito fai ogni cosa in un processo lineare e questo è qualcosa in contrasto con l'elaborazione parallela. e devi sempre usare il tuo thread principale per gli aggiornamenti grafici dei dispositivi che rendono ancora più difficile dividere le attività tra thread.


1
Il threading non è difficile. :) È solo qualcosa che molte persone non imparano mai a fare correttamente, quindi pensano che sia difficile a causa dell'inesperienza. Soprattutto nei giochi molti algoritmi e strutture di dati di base sono abbastanza facili da gestire con più thread. Gli aggiornamenti della fisica, ad esempio, possono essere suddivisi in isole di oggetti e ciascuno è passato a un thread diverso per l'integrazione e la risoluzione. Allo stesso modo, l'abbattimento di oggetti per la grafica è praticamente completamente privo di contese di accesso ai dati in lettura e scrittura.
Sean Middleditch,

@seanmiddleditch Non ho detto che usare i thread in sé sia ​​una cosa difficile, ma riuscire a usare i thread in modo efficace e bilanciarli per condividere lo stesso carico è qualcosa di difficile.
Ali1S232
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.