2012-12-11 15 views
6

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?

+0

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? –

+0

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

+0

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. –

risposta

3

Bene, tecnicamente, 1 CPU esegue solo un segmento di codice alla volta. Il tuo OS scheduler modifica processi/thread in una frazione di millisecondi che ti dà l'illusione di eseguire più processi contemporaneamente.

Un modo per notificare al runtime che il thread è terminato per ora sta chiamando Thread.yield. C'è un ciclo occupato nel tuo codice che non aiuta la tua situazione. Mantiene la CPU occupata senza fare nulla.

while(otherBuffer.isFinished() == false) 

si dovrebbe usare Loks invece di ciclo occupato o si può provare a chiamare Thread.yield dentro quel ciclo while per una spinta iniziale di prestazioni. Tra l'altro, date un'occhiata allo semaphore che è la soluzione più semplice per tali problemi produttore-consumatore. Se si desidera mantenere la base di codice corrente, è possibile utilizzare un blocco per buffer.

0

Creare filo come le classi come qui di seguito

class Threadcalling implements Runnable 
    { 

     @Override 
     public void run() { 
} 
} 

così lo chiamano utilizzando come qui di seguito

Thread t=new Thread(new Threadcalling()); 
        t.start(); 

È possibile creare molte classi di thread come questo e lo chiamano come parallelo. non farà alcun problema. lavorare bene.

Problemi correlati