分析线程调度

为了确定游戏进程线程是否得到适当利用和调度以实现最佳性能,您需要考虑以下几点。

  • Frame pacing
  • 多线程和线程并行化
  • CPU 核心亲和性

多线程处理

许多游戏和游戏引擎都使用多线程将 CPU 工作划分为逻辑任务,这些任务可以独立运行。一种典型的配置是:一个游戏线程用于输入和游戏逻辑,一个渲染线程用于准备和提交要绘制的对象,以及多个工作线程用于动画或音频等其他子任务。

我们建议并行化线程,以充分利用多线程的性能优势。一个示例是游戏线程和渲染线程在不同核心上部分或完全并发运行的场景。这种情况并非总是可行,例如在存在共享数据依赖项的情况下;不过,如果可行,这可能会缩短 CPU 时间,从而可能提高帧速率。

主线程和渲染线程以及工作器线程和音频线程实现良好并行化的游戏
图 1. 主线程和渲染线程以及工作器线程和音频线程实现良好并行化的游戏

CPU 核心亲和性

一个会显著影响 CPU 工作负载性能的因素是它们在核心上的调度方式。这可能分为两个组成部分:

  • 游戏线程是否在最适合其工作负载的核心上运行。
  • 游戏线程是否在核心之间频繁切换。

现代设备通常使用一种称为异构计算的架构,其中核心具有不同的性能级别:

  • 一个或几个核心可提供最高峰值性能,但会消耗更多电量。这些核心有时称为“大”核心。
  • 其他核心的峰值性能较低,但能效更高。这些核心有时称为“小”核心。
  • 可选:一个或多个核心,可在性能和能耗之间取得平衡。这些核心有时称为“中”核心。

您可以在进行轨迹分析时,通过在配置文件中启用 CPU 来调查 CPU 使用情况下的 CPU 线程行为。通过放大轨迹中 <200 毫秒的部分,您可以查看设备 CPU 核心上运行的各个进程。通常,较小的核心对应于较小的索引(例如,CPU“0”-“3”),而较大的核心对应于较高的索引(例如,CPU“6”-“7”),如果存在中间核心,则会占用介于两者之间的索引(例如,CPU“5”-“6”)。 这是常见的做法,但不能保证。

如果您发现某些线程被调度到无法满足其性能或能耗需求的 CPU 上,请考虑手动为这些线程设置 CPU 亲和性。

主要在大型核心(CPU 6-7)上运行的主线程和渲染线程游戏,以浅蓝色显示
图 2. 主要在大型核心(CPU 6-7)上运行主线程和渲染线程的游戏,以浅蓝色显示

您还可以观察线程是否在核心之间切换。 此类核心切换会因情境切换以及核心缓存/寄存器中的状态丢失而产生一些开销。

具有在核心之间切换的主线程 (Thread-7) 和渲染线程 (Thread-8) 的游戏,以紫色显示
图 3. 具有在核心之间切换的主线程 (Thread-7) 和渲染线程 (Thread-8) 的游戏,以紫色显示

为线程设置 CPU 亲和性会指示系统在游戏处于前台时,将该线程调度到给定的核心上。执行此操作时,您需要考虑以下几个因素:

  • 平台软件无法根据运行时因素(例如负载和热节流)动态调整任务放置。
  • 在不同设备上进行性能测试可能会产生截然不同的性能特征,尤其是在设备的价格点或发布日期差异很大的情况下。

    较新或较昂贵的设备可能可以在小核心上轻松运行给定的工作负载,但较旧或更实惠的设备可能需要更大的核心才能按时完成同一工作负载。

  • 通过强制将亲和性设置为大核心,您可能会不必要地增加电池消耗和热负荷。

出于这些原因,一般最好避免手动设置 CPU 亲和性。