多线程游戏循环渲染/更新(boost-asio)

时间:2012-11-29 21:34:39

标签: multithreading opengl rendering boost-asio boost-thread

所以我有一个单线程游戏引擎类,它有单独的输入,更新和渲染功能,我刚开始学习使用精彩的boost库(asio和线程组件)。我正在考虑将更新渲染功能分成不同的线程(并且可能将输入更新分开彼此相互作用)。当然这些函数有时会访问内存中的相同位置,所以我决定使用boost / thread的strand功能来阻止它们同时执行。

现在我的主游戏循环看起来像这样:

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();
}

正如您所看到的,在循环开始之前:输入 - >更新 - >渲染 - >延迟 - >重复

每个人都是一个接一个地跑。如果我使用多线程,我将不得不使用 strands ,以便不会同时运行更新和渲染。那么,在这里使用多线程仍然值得吗?它们仍然基本上在不同的核心中一次运行一个。我基本上没有多线程应用程序的经验,所以感谢任何帮助。

哦,还有一件事:我正在使用OpenGL进行渲染。像这样的多线程会影响OpenGL以任何方式呈现的方式吗?

1 个答案:

答案 0 :(得分:0)

您对所有处理程序使用相同的 strand ,因此根本没有多线程。此外,您的 deadline_timer 的范围为Start(),您不会将其传递到任何地方。在这种情况下,你将无法从处理程序重新启动它(注意它不是“间隔”计时器,它只是一个“一次调用计时器”)。

我认为这个“改造”没有意义,因为在这个例子中你没有从 asio 和/或线程中获得任何好处。

这些方法(输入,更新,渲染)太大而且做了很多事情,你不能不阻塞地调用它们。很难说,正是因为我不知道游戏及其运作方式,但我更愿意采取以下步骤:

  • 尝试修改网络i / o,使其完全异步
  • 尝试使用所有CPU核心

关于您尝试过的内容:我认为如果您在代码中搜索真正可以并行执行的操作,则可能会这样做。例如:如果你为每个NPC计算一些不依赖于其他字符的东西,你可以io_service.post()分别使用所有运行io_service.run()的线程。所以你的程序保持单线程,但是你可以在一些“大”操作中使用7个其他线程