Sto scrivendo un gioco in Android/OpenGL e sto tentando di separare la mia logica OpenGL (rendering) dalla logica di aggiornamento del gioco, eseguendone ognuno sul proprio thread per migliorare le prestazioni.Android: thread non in esecuzione in parallelo
sono riuscito ad ottenere ogni esecuzione sul proprio thread, tuttavia secondo il Tracer nel DDMS, i fili sono ancora in esecuzione in sequenza (il mondo è il mio gioco aggiornamento discussione):
See URL, non lo faccio avere i privilegi di immagine: http://img849.imageshack.us/img849/9688/capturegff.png
I thread non sembrano eseguire il codice allo stesso tempo. ho inizializzare il filo mondo come segue:
public class World implements Runnable {
Thread thread;
public World(...) {
...
// Initialise the player/ball objects
initialiseObjects();
thread = new Thread(this, "World");
thread.start();
}
}
Ho implementato il mio sincronizzazione tra i due thread. Utilizzando un approccio simile a quello in Replica Island, ho due buffer di rendering: il thread di aggiornamento (dovrebbe idealmente) scrivere su uno dei buffer mentre il thread di rendering sta leggendo l'altro buffer. Il buffer contiene le informazioni necessarie per il rendering per disegnare ogni sprite. Una volta che il thread di aggiornamento ha terminato di aggiornare il suo buffer e il renderer ha finito di disegnare, scambiano i buffer e le ripetizioni del processo.
Nel codice dal filo aggiornamento di gioco (codice simile nel thread rendering):
currBuffer.write();
player.draw(currBuffer.getNext());
ball.draw(currBuffer.getNext());
if (particleEffect != null) {
particleEffect.draw(currBuffer);
}
currBuffer.finished();
while(otherBuffer.isFinished() == false) {
//otherBuffer is finished once the render thread has finished drawing
}
DrawBuffer tempBuffer = currBuffer;
currBuffer = otherBuffer;
otherBuffer = tempBuffer;
currBuffer.changed();
while(otherBuffer.isChanged() == false) {
//otherBuffer is changed once the render thread has also swapped buffered
}
non riesco a vedere come il codice sopra potrebbe comportare l'esecuzione sequenziale di fili, se non sono mai tentato multi-threading prima quindi è possibile che sto facendo qualcosa di fondamentalmente sbagliato. Il mio tentativo di accelerare il gioco l'ha reso notevolmente più lento e molto meno fluido. Qualche idea sul perché i thread non funzionino in parallelo?
UPDATE: Il problema era che il processore del mio telefono era solo single core. Ero sicuro che l'Incredible S fosse dual core, ma purtroppo è solo singolo. L'ho provato su S2 e ha effettivamente eseguito i thread in parallelo.
Tuttavia, qual è il vantaggio del multi-threading se solo i nuovi telefoni sul mercato lo supportano? Non capisco come Replica Island abbia gestito prestazioni migliori su telefoni single core precedenti implementando il multi-threading. Sicuramente l'overhead aggiunto nella sincronizzazione tra i thread dovrebbe portare a prestazioni più lente se non c'è un secondo core da sfruttare?
Il multi-threading ha portato a prestazioni più lente sul single core a causa della necessità di generare il buffer che viene poi passato al thread di draw. Sul dual core, era 5-10% più veloce, anche se a circa 500 folletti il ciclo di aggiornamento richiedeva più tempo del ciclo di trazione a causa del buffer, limitando così i guadagni di velocità. Ovviamente con l'ottimizzazione posso migliorarlo, ma la domanda diventa se vale la pena supportare il multithreading a scapito dei processori single core. È possibile determinare i processori di un telefono al fine di determinare se utilizzare il multi-threading o meno durante il runtime?
Se si dispone di un solo core ed entrambi i task sono limitati dalla CPU, non possono realmente essere eseguiti in parallelo. Inoltre, cosa c'è dentro questi cicli while? Sono davvero vuoti? –
Grazie @David Schwartz - questo è stato davvero il problema. Ero sicuro che l'Incredible S fosse dual core, ma purtroppo è solo singolo. L'ho provato su S2 e ha effettivamente eseguito i thread in parallelo. Tuttavia, qual è il vantaggio del multi-threading se solo i nuovi telefoni sul mercato lo supportano? Non capisco come Replica Island abbia gestito prestazioni migliori su telefoni single core precedenti implementando il multi-threading. Sicuramente l'overhead aggiunto nella sincronizzazione tra i thread dovrebbe portare a prestazioni più lente se non c'è un secondo core da sfruttare? – awr
Se le attività non sono limitate dalla CPU, possono esserci enormi vantaggi nel multithreading. Se un compito non può progredire in avanti (diciamo perché è in attesa di I/O), un altro può. Tuttavia, se c'è un solo core e le attività sono limitate dalla CPU, il multithreading non aiuta. –