-1

だから私はシングルスレッドのゲームエンジンクラスを持っていて、それは入力、更新、レンダリングのための別々の関数を持っています、そして私は素晴らしいブーストライブラリ(asioとスレッドコンポーネント)の使い方を学び始めました。そして、更新関数とレンダリング関数を別々のスレッドに分離することを考えていました(そして、おそらく入力関数と更新関数も互いに分離することもできます)。もちろん、これらの関数はメモリ内の同じ場所にアクセスすることがあるので、ブースト/スレッドのストランド機能を使用して、それらが同時に実行されないようにすることにしました。

現在、私のメインのゲームループは次のようになっています。

void SDLEngine::Start()
{
    int update_time=0;
    quit=false;
    while(!quit)
    {
        update_time=SDL_GetTicks();
        DoInput();//get user input and alter data based on it
        DoUpdate();//update game data once per loop
        if(!minimized)
            DoRender();//render graphics to screen
        update_time=SDL_GetTicks()-update_time;
        SDL_Delay(max(0,target_time-update_time));//insert delay to run at desired FPS
    }
}

別々のスレッドを使用した場合、次のようになります。

void SDLEngine::Start()
{
    boost::asio::io_service io;
    boost::asio::strand strand_;
    boost::asio::deadline_timer input(io,boost::posix_time::milliseconds(16));
    boost::asio::deadline_timer update(io,boost::posix_time::milliseconds(16));
    boost::asio::deadline_timer render(io,boost::posix_time::milliseconds(16));
    //
    input.async_wait(strand_.wrap(boost::bind(&SDLEngine::DoInput,this)));
    update.async_wait(strand_.wrap(boost::bind(&SDLEngine::DoUpdate,this)));
    render.async_wait(strand_.wrap(boost::bind(&SDLEngine::DoRender,this)));
    //
    io.run();
}

ご覧のとおり、ループが進む前に、[入力]->[更新]->[レンダリング]->[遅延]->[繰り返し]を選択します。

それぞれが次々に実行されました。マルチスレッドを使用した場合、更新とレンダリングが同時に実行されないように、ストランドを使用する必要があります。それで、ここでマルチスレッドを使用することはまだ価値がありますか?それらは基本的に、別々のコアで一度に1つずつ実行されます。私は基本的にマルチスレッドアプリケーションの経験がないので、助けていただければ幸いです。

ああ、そして別のこと:私はレンダリングにOpenGLを使用しています。このようなマルチスレッドは、OpenGLのレンダリング方法に何らかの影響を及ぼしますか?

4

1 に答える 1

0

すべてのハンドラーに同じストランドを使用しているため、マルチスレッドはまったくありません。また、deadline_timerはスコープ内にStart()あり、どこにも渡しません。この場合、ハンドラーから再起動することはできません(「間隔」タイマーではなく、単なる「ワンコールタイマー」であることに注意してください)。

この例では、 asioやスレッドのメリットがまったく得られていないため、この「改良」には意味がありません。

これらのメソッド(入力、更新、レンダリング)は大きすぎて多くのことを実行するため、ブロックせずに呼び出すことはできません。ゲームの内容とその仕組みがわからないため、正確に言うのは難しいですが、次の手順を実行したいと思います。

  • 完全に非同期になるようにネットワークI/Oを刷新してみてください
  • すべてのCPUコアを使用してみてください

あなたが試したことについて:今、実際に並行して実行できるアクションをコードで検索すれば、それは可能だと思います。例:他のキャラクターに依存しないNPCごとに計算する場合、それぞれが現在io_service.post()実行中のすべてのスレッドを使用することができますio_service.run()。したがって、プログラムはシングルスレッドのままですが、たとえば、いくつかの「大きな」操作で他の7つのスレッドを使用できます。

于 2012-11-30T05:21:25.373 に答える