Multi-piattaforma multi-threading: quali sono le vere sfide?


21

Mentre una libreria come SDL fornisce un'API wrapper multipiattaforma per il threading, penso che sarebbe ingenuo presumere che ciò porti direttamente a un facile sviluppo di giochi su piattaforme molto diverse (desktop / mobile).

Qual è il modo migliore per affrontare lo sviluppo in questo modo (data qualsiasi API di threading multipiattaforma) considerando quanto segue:

  • diversi numeri di core
  • capacità di elaborazione molto diverse per core
  • Un'architettura di sistema generalmente diversa con es. latenze diverse per l'accesso a cache, RAM e I / O

Ho la sensazione che l'unico modo per farlo sia valutare quanti thread possono essere eseguiti per ciascun dispositivo che intendi supportare e scoprire qual è il minimo comune denominatore. Tuttavia, questo mi lascia ancora al buio per quanto riguarda la quantità totale di elaborazione disponibile. Ho ragione nel ritenere che l'unico modo per farlo efficacemente sia sviluppare attivamente per il dispositivo mobile con le specifiche più basse che intendo supportare, durante lo sviluppo? - ovvero il minimo comune denominatore? Questo dovrebbe essere approssimativamente sufficiente? O c'è di più?

EDIT: Per favore, altri potrebbero offrire ulteriore esperienza al riguardo, poiché non credo che la mia domanda abbia ancora ricevuto una risposta completa.


Dato che la mia risposta non risponde completamente alla tua domanda, potresti dettagliare cosa manca / cosa vuoi sapere? Potrei non essere un grande scrittore ma ho gestito questo tipo di problema più di una volta.
Valmond,

Non hai davvero risposto alla domanda, che riguardava le difficoltà del multithreading e come superarle quando si sviluppano piattaforme con capacità di threading diverse . Vedi il mio paragrafo sotto i punti elenco. Parli di dimensioni e risoluzioni dello schermo - quelle non hanno nulla a che fare con la mia domanda - leggi il titolo.
Ingegnere

1
Immagino che la difficoltà provenga da ciò per cui vuoi usare i thread. Una cosa è avere un thread helper che fa qualcosa sul lato, e completamente un altro per provare a spremere gli ultimi bit di prestazioni da una macchina a 8 core. Per come la vedo io, i thread SDL sono principalmente pensati per il primo, non quest'ultimo.
Jari Komppa,

Risposte:


11

Parli di "difficoltà di multithreading" ma di quali difficoltà stai effettivamente parlando? In un certo senso stai citando un problema fantasma che potrebbe anche non esistere. La vera sfida è quella che fai per te stesso: se sei assolutamente determinato a ottenere ogni ultima goccia di energia da un pezzo di hardware, ciò comporta l'utilizzo dell'hardware per ottenere i migliori risultati, ma aumenta anche il divario tra la macchina più potente e il meno potente. Ciò implica che se hai un gioco che sfrutta al massimo una PS3 (ad esempio), non puoi comunque eseguirlo su un cellulare economico, quindi il tuo problema non è più "come posso ottenere 1 programma lavorare su hardware molto diverso "ma diventa" come posso implementare 1 idea di gioco in diversi modi in modo che funzioni su hardware alimentato diversamente ".

Mentre una libreria come SDL fornisce un'API wrapper multipiattaforma per il threading, penso che sarebbe ingenuo presumere che ciò porti direttamente a un facile sviluppo di giochi su piattaforme molto diverse (desktop / mobile).

Facile sviluppo di giochi - certo. Multithreading ottimale, no. Ma non è necessario il multithreading per creare giochi. Per rendere quelli ad alte prestazioni, sicuramente aiuta. Ma molti grandi giochi girano in un unico thread.

Qual è il modo migliore per affrontare lo sviluppo in questo modo (data qualsiasi API di threading multipiattaforma) considerando quanto segue:

  • diversi numeri di core
  • capacità di elaborazione molto diverse per core
  • Un'architettura di sistema generalmente diversa con es. latenze diverse per l'accesso a cache, RAM e I / O

Invece di provare ad assegnare i sistemi ai thread, assegnare attività ai thread. Fornisci a ogni attività i dati necessari per l'esecuzione e trasferisci le attività su qualsiasi hardware disponibile. Di solito avrai una sorta di pool di thread per sottrarre i vari core o processori e un task manager che ha una coda di task e li consegna ai vari thread quando il thread segnala che è finito il compito precedente ed è pronto per uno nuovo. L'hardware con più core ovviamente completerà le attività più rapidamente e sarà in grado di renderizzare più rapidamente. Specializzare questo sistema in modo che funzioni in modo ottimale su sistemi con caratteristiche diverse diventa un problema di ottimizzazione avanzato, ma può basarsi su determinate euristiche (ad es. Un'attività che non

Tuttavia, la scomposizione delle caratteristiche del gioco in compiti discreti è una questione piuttosto complessa e spesso non vale la pena, a meno che non si sia molto sicuri di aver bisogno delle prestazioni, quindi la maggior parte non ci proverà nemmeno.

Qualche ulteriore lettura:

http://www.gamasutra.com/view/feature/1830/multithreaded_game_engine_.php - consultare la sezione "dati paralleli". Con questo modello i dati vengono suddivisi su più attività identiche e trasferiti su singoli thread.

http://software.intel.com/en-us/articles/designing-the-framework-of-a-parallel-game-engine/ - abbastanza denso, descrive le cose a livello di sistema operativo piuttosto che a livello di gioco.

http://drdobbs.com/high-performance-computing/216500409 - non specifico per il gioco, ma completamente pertinente in termini di spiegazione di come è necessario suddividere i compiti.

http://www.itfgaming.com/news/tech-focus-crysis-2-and-the-future-of-cryengine-3 - A metà di questa intervista c'è un aneddoto su come sono passati a un sistema basato su attività .


Punti molto buoni. E vero, ho usato la parola "difficoltà" quando "sfide" sarebbe stato più preciso. Hai detto: "La scomposizione delle caratteristiche del gioco in compiti discreti è una questione piuttosto complessa e spesso non vale la pena, a meno che tu non sia molto sicuro di aver bisogno delle prestazioni, quindi la maggior parte non ci proverà nemmeno". Puoi approfondire questo? Fornire fonti? È un po 'vago ma direi che stai arrivando al nocciolo della questione lì.
Ingegnere

Mi dispiace, ho pensato che questo tipo di approccio fosse ben noto. Elaborerò nella risposta.
Kylotan,

4

Quando ho realizzato i giochi per dispositivi mobili, abbiamo inizialmente sviluppato una versione "gold" (ovvero un gioco completamente funzionale) e poi l'abbiamo suddivisa in 3 versioni principali (schermo grande, schermo medio e schermo piccolo). Questi sono stati ulteriormente convertiti in 11 versioni: grafica impegnativa (leggere richiede molta memoria / CPU) vs profilo basso ecc. (C'erano anche un paio di versioni di piattaforme speciali).

Il problema più grande era (quello era il mio lavoro tra gli altri) isolare le piattaforme necessarie e determinare quelle versioni e come crearle (es. Grande schermo ma basso profilo dovrebbe essere una versione declassata di grande schermo / ciao profilo o dovrebbe essere schermo / profilo di medie dimensioni reso grande schermo?).

Ovviamente abbiamo programmato questo in mente, quindi i giochi erano molto vagamente legati alle dimensioni dello schermo.

HTH

[modifica] Ciò che intendevo dire era che devi dividere le tue piattaforme target in diverse qualità (es. 1 core, 2 core, 1 core ma due volte più veloce ...) Quindi decidi quanti target virtuali vuoi (ad esempio " solo uno "o" Low, Mid, Hi ") Quindi posiziona tutte le piattaforme nella rispettiva" qualità "e per ciascuna qualità, prendi il minimo denominatore e" porta "il codice in modo che sia conforme a tali requisiti (cioè funziona ed è veloce abbastanza).

Potrebbe sembrare che devi farlo con molte congetture, ma puoi già trovare la peggiore qualità con la piattaforma peggiore. Sceglierei ogni qualità successiva almeno "due volte più buona" della prima, questo probabilmente non genererebbe più di 3-4 "qualità". Se il codice viene portato da una versione gold, qualsiasi piattaforma che non funziona abbastanza bene potrebbe semplicemente essere retrogradata a una "qualità" inferiore per accelerarla. Qualsiasi nuova piattaforma potrebbe anche essere facilmente collocata nella giusta qualità.


Al di là della testa, quanto tempo di lavoro diresti che quel progetto aveva sia in fase di progettazione che di sviluppo, per accogliere una versione multipiattaforma come questa? Solo una media approssimativa sarebbe di aiuto.
Ingegnere

1
Bene, come abbiamo fatto in più lingue (inglese, francese, spagnolo, portoghese, tedesco e italiano in un pacchetto + qualsiasi lingua necessaria di giorno in giorno, taiwanese, turco, russo ...) e avevamo nuove piattaforme che dovevamo "port" tutti i nostri giochi a distanza di pochi mesi (leggi una nuova classe di cellulari) in realtà avremmo perso molto tempo non andando in questo modo, sarebbe stato davvero impossibile in realtà senza un grosso problema. Il design del "framework" è stato eseguito in fuga mentre ho appreso di diversi cellulari e sono giunto a maturità dopo forse 3-4 anni. Un investimento degno però.
Valmond,

1

Ho la sensazione che l'unico modo per farlo sia valutare quanti thread possono essere eseguiti per ciascun dispositivo che intendi supportare e scoprire qual è il minimo comune denominatore.

Non necessariamente: potrebbe esserci speranza per una soluzione più dinamica, ma questo dipende dal problema reale che si sta tentando di risolvere (se presente). Sei un po 'vago nella tua domanda, quindi anche la mia risposta deve essere vaga.

Se il raggruppamento di piattaforme su cui si intende eseguire ha la capacità di enumerare l'hardware tramite un'API, è possibile utilizzare tale interfaccia per rilevare il numero massimo di thread che il sistema può gestire e utilizzarlo come base per il numero di thread dell'applicazione dovrebbe creare. L'unica sfida qui è trovare quelle API; indipendentemente dal fatto che tu vada a livello di sistema operativo o cerchi una libreria di terze parti o un SDK / API multipiattaforma dipende da te e dipende dalle piattaforme che stai cercando di supportare.

Qual è il modo migliore per affrontare lo sviluppo in questo modo (data qualsiasi API di threading multipiattaforma) considerando quanto segue:

different numbers of cores
vastly different processing capabilities per core
A generally different systems architecture with eg. different

latenze per l'accesso a cache, RAM e I / O

Secondo me, nessuna di queste cose dovrebbe essere la tua preoccupazione. La tua preoccupazione dovrebbe essere la costruzione del tuo gioco. Se si incontra un collo di bottiglia e si decide che sarebbe meglio generare un thread separato per un'attività specifica ad alta intensità di processore, quindi spawn il thread e lasciare che il sistema operativo e altri software di livello inferiore decidano come manipolare l'hardware per gestire il threading.

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.