2012-12-11 31 views
6

Android/OpenGLでゲームを作成していて、パフォーマンスを向上させるために、それぞれ独自のスレッドでOpenGL(レンダリング)ロジックをゲームの更新ロジックから分離しようとしています。Android:スレッドが並行して実行されていない

私はしかし、DDMSでのトレーサーによると、スレッドがまだ(世界は私のゲーム更新スレッドである)を順次実行している、それぞれが独自のスレッドで実行されている得ることをどうにか:

参照URLを私はないそうであるように画像権限があります。 http://img849.imageshack.us/img849/9688/capturegff.png

スレッドはコードを同時に実行していないようです。 次のように私は世界のスレッドを初期化:私は2つのスレッド間で、私自身の同期を実装しました

public class World implements Runnable { 

    Thread thread; 

    public World(...) { 
    ... 
     // Initialise the player/ball objects 
     initialiseObjects(); 

     thread = new Thread(this, "World"); 
     thread.start(); 
} 
} 

。レプリカアイランドに似たアプローチを使用して、私は2つのレンダーバッファを持っています:レンダリングスレッドが他のバッファを読み込んでいる間に更新スレッド(理想的には)がバッファの1つに書き込みます。バッファには、レンダラーが各スプライトを描画するために必要な情報が含まれています。更新スレッドがバッファの更新を完了し、レンダラーが描画を完了すると、バッファを交換してプロセスを繰り返します。

ゲーム更新スレッド(レンダリングスレッドで同様のコード)からのコードで

:私は決してきませんけれども、私は、上記のコードは、スレッドの順次実行につながる可能性があるかを確認することはできません

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 
    } 

私は根本的に何かをやっている可能性があります前にマルチスレッドをしようとしました。ゲームをスピードアップしようとした私の試みは、それを目立って遅く、滑らかにしませんでした。スレッドが並行して実行されない理由は何ですか?

更新日: 問題は私の携帯電話のプロセッサがシングルコアであることでした。私は信じられないほどのSがデュアルコアだと確信していたが、それは唯一のものである。私はS2でそれを試して、それは実際に並列にスレッドを実行しました。

ただし、市販されている最新の携帯電話だけでサポートしているのであれば、マルチスレッドの利点は何ですか?マルチスレッドを実装することで、レプリカアイランドが旧式のシングルコア電話でどのように優れたパフォーマンスを管理したかはわかりません。確かに、2番目のコアがない場合は、スレッド間の同期における追加のオーバーヘッドによってパフォーマンスが低下するはずです。

マルチスレッドでは、バッファを生成して描画スレッドに渡す必要があるため、シングルコアでのパフォーマンスが低下しました。デュアルコアでは5〜10%高速化されましたが、約500スプライトで、更新サイクルがバッファーによる描画サイクルよりも長くかかってしまい、速度の向上が制限されていました。明らかに最適化を行うことでそれを改善することができますが、シングルコアプロセッサを犠牲にしてマルチスレッドをサポートする価値があるのか​​どうかという疑問が生じます。実行時にマルチスレッドを使用するかどうかを判断するために、電話機のプロセッサーを特定することは可能ですか?

+0

コアが1つしかなく、両方のタスクがCPUによって制限されている場合は、実際には並列実行できません。また、これらのwhileループの内部には何がありますか?彼らは本当に空のループですか? –

+0

ありがとう@David Schwartz - それは確かに問題でした。私は信じられないほどのSがデュアルコアだと確信していたが、それは唯一のものである。私はS2でそれを試して、それは実際に並列にスレッドを実行しました。しかし、マルチスレッドのメリットは、市販されている最新の携帯電話だけでサポートされている場合です。マルチスレッドを実装することで、レプリカアイランドが旧式のシングルコア電話でどのように優れたパフォーマンスを管理したかはわかりません。確かに、2番目のコアがない場合は、スレッド間の同期における追加のオーバーヘッドによってパフォーマンスが低下するはずです。 – awr

+0

タスクがCPUによって制限されていない場合、マルチスレッドに大きな利点があります。 1つのタスクが進捗を進めることができない場合(例えば、I/Oを待っているため)、別のタスクが進行することができます。ただし、コアが1つしかなく、タスクがCPUに制限されている場合、マルチスレッド化は役に立ちません。 –

答えて

3

技術的には、1 CPUは一度に1つのコードセグメントしか実行しません。 OS schedulerは、プロセス/スレッドを数ミリ秒で変更します。これにより、複数のプロセスを同時に実行するような錯覚が得られます。

スレッドが現在実行されていることをランタイムに通知する方法は、Thread.yieldです。あなたの状況に役立たないあなたのコードにビジーなループがあります。それは何もしないでCPUをビジーに保ちます。

while(otherBuffer.isFinished() == false) 

あなたの代わりにビジーループのLoksを使うべきか、初期性能の向上のためにそのwhileループ内のThread.yieldを呼び出して試すことができます。 Btw、またそのような生産者 - 消費者問題の最も簡単な解決策であるsemaphoreを見てください。現在のコードベースを保持したい場合は、バッファごとにロックを使用できます。

0

class Threadcalling implements Runnable 
    { 

     @Override 
     public void run() { 
} 
} 

以下のようなクラスはそうあなたはこのような多くのスレッドクラスを作成し、パラレルとしてそれを呼び出すことができます

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

以下のように使用してそれを呼び出すようスレッドを作成します。それはどんなprobsも作っていない。うまくできた。

関連する問題