multithreading - 关于渲染循环策略的思考

标签 multithreading synchronization rendering game-engine

我知道这些注意事项的数百种变化已在网上发布。但是,我还没有找到能够解决我的确切问题的任何东西,因此希望您能帮助我了解情况。

我目前正在使用OpenGL在Java中进行2D游戏开发。使用的语言和图形库与我的问题无关,尽管它具有更一般的特征。

我正在尝试设计一个通用的游戏循环,该循环可以或多或少地用于具有中等沉重图形(主要是位图纹理)甚至可能具有较重游戏逻辑(AI,碰撞检测等)的任何游戏。

基本上,我希望维护一个可以被更新(位置,速度和其他与游戏相关的更新)和渲染(纹理/帧在更新位置)的对象的列表/数组/缓冲区,并且尽可能地流畅和高效。

1)一个线程用于更新+渲染

我尝试并仅使用一个线程(好了,在计算用户输入时为两个)放弃了顺序解决方案。

  • 计算更改并更新缓冲区对象
  • 将更新位置的纹理渲染到后缓冲
  • 将后缓冲区交换到前面的

  • 显然,在交换缓冲区阻塞硬件的同时,浪费了很多好的计算时间,这要求一种更有效的解决方案

    2)一个用于更新的线程,一个用于呈现的线程

    通过将程序分为更新线程和渲染线程并同步对共享缓冲区的访问,我应该能够确保相当稳定的帧速率。对共享缓冲区的同步访问可以通过多种方式来完成,但是它们都有一个共同点。它们都禁止线程并发。尽管这可能是一个公平的权衡,但我想知道是什么使同步变得必要。

    3)与2相同,但没有同步

    我确实了解许多由于并发线程的粗心实现而引起的问题。生产者/消费者,读者/作家和类似情况导致潜在的僵局。但是,我不明白,如果满足以下条件(并且应该满足),为什么我需要确保共享数据的同步:
  • 渲染线程只能从共享缓冲区
  • 中读取
  • 更新线程可以读取和写入共享缓冲区(因此它是唯一的“写入器”)
  • 游戏运行时,共享缓冲区永远不会为空或已满
  • 线程永远不会休眠
  • 渲染不一定是100%准确的。如果某些共享库尚未更新,导致它们比其他对象落后一个更新步骤(即,大约10-20毫秒),则任何人都不会注意到。

  • --

    所以...我在这里想念什么明显的东西?为什么需要为此设置进行同步?
  • 如果未正确同步,线程可以缓存数据导致问题吗?
  • 还是如果不幸不幸中断了写线程,数据可能会以某种方式乱码吗?
  • 或我提出的策略使它变得无用时是否存在一般性问题?

  • 任何想法,评论或建议都是最欢迎的。或者,如果已经在其他地方解决了这个特定问题,我将为您提供引用。

    最佳答案

    不同步的方法对您来说很好。如果这是库存的Intel硬件,则加倍。我仍然不会使用它。

    不同步的并发几乎永远无法可靠运行的原因是,处理器可以自由分配何时在主RAM和缓存之间进行存储和加载。这可以破坏几乎所有不同步的协议(protocol)。但是,正如您所说,如果您的应用程序中的场景从未发生过突然变化,那么没人会注意到。所有数据都将进入RAM,并且或早或晚对其他线程可见。

    但是,您无法保证何时何地,以什么顺序进行操作,这在理论上可能使您以奇怪的方式混合两个后续帧(在场景或其光照的突然改变之前和之后)。

    根据您的编程语言及其内存模型(我想C++早于C++ 11?),您可能会发现轻量级同步原语,其保证的副作用是适当的内存障碍,其对性能的影响可以忽略不计。这是我建议的起点。极端的性能优化(超出可以证明的安全范围)应该是优化引擎的最后阶段。

    1)i86永远不会重新订购商店。我不认为这在任何地方都有记载,我也不想依赖它。您仍然可以对读取进行重新排序,因此无论如何对您的情况没有帮助。

    关于multithreading - 关于渲染循环策略的思考,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11403359/

    相关文章:

    java - 在 Java 6 中,为什么即使低优先级线程让步,高优先级线程也不会运行?

    multithreading - C++98:在多线程应用程序中访问共享全局对象需要 volatile

    java - Java 中的同步?

    java - 如何在 GPU 上而不是 CPU 上渲染? -Java-

    c - Vulkan - 同步对单个缓冲区的访问

    ios - 使用单个共享后台线程进行 iOS 数据处理?

    c++ - 了解线程构造函数的基础知识

    java - 资源为空时锁定线程

    java - 我需要同步这个吗?如果可以的话,该怎么办呢?

    geometry - 透视投影: Proving that 1/z is Linear?