6

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

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

画像権限がないのでURLを参照してください:http: //img849.imageshack.us/img849/9688/capturegff.png

スレッドは同時にコードを実行していないようです。ワールドスレッドを次のように初期化します。

public class World implements Runnable {

    Thread thread;

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

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

2つのスレッド間に独自の同期を実装しました。レプリカアイランドと同様のアプローチを使用して、2つのレンダリングバッファーがあります。更新スレッドは(理想的には)一方のバッファーに書き込み、レンダリングスレッドはもう一方のバッファーを読み取ります。バッファには、レンダラーが各スプライトを描画するために必要な情報が含まれています。更新スレッドがバッファーの更新を終了し、レンダラーが描画を終了すると、バッファーを交換し、プロセスが繰り返されます。

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

    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スプライトでは、バッファが原因で更新サイクルが描画サイクルよりも長くかかり、速度の向上が制限されていました。明らかに最適化によってそれを改善できますが、問題は、シングルコアプロセッサを犠牲にしてマルチスレッドをサポートする価値があるかどうかということです。実行時にマルチスレッドを使用するかどうかを決定するために、電話のプロセッサを決定することは可能ですか?

4

2 に答える 2

3

まあ、技術的には、1つのCPUは一度に1つのコードセグメントのみを実行します。OSスケジューラは、プロセス/スレッドを数ミリ秒で変更します。これにより、複数のプロセスを同時に実行しているように見せることができます。

スレッドが今のところ完了したことをランタイムに通知する方法は、Thread.yieldを呼び出すことです。あなたの状況を助けないあなたのコードにビジーループがあります。何もせずにCPUをビジー状態に保ちます。

while(otherBuffer.isFinished() == false)

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

于 2013-01-04T04:40:29.843 に答える
0

以下のようなクラスとしてスレッドを作成します

class Threadcalling implements Runnable
    {

        @Override
        public void run() {
}
}

以下のように呼んでください

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

このような多くのスレッドクラスを作成して、並列として呼び出すことができます。それは何の問題も起こさないでしょう。うまくできた。

于 2013-01-04T05:10:50.970 に答える