估算 CPU 和 GPU 帧处理时间

估计 CPU 和 GPU 帧处理时间(帧时间)对于了解应用的性能和找到瓶颈至关重要。使用 AGI 对应用进行性能剖析时,系统分析器会提供可用于估计帧时间的轨迹数据。

CPU 时间

在 AGI 中,您可以在系统配置文件的 CPU 轨道中查看 CPU 总帧时间和活动帧时间。

总计 CPU 时间

如需衡量总 CPU 时间,请选择时间范围,该范围应包含连续帧提交事件之间的时间。帧提交事件为 eglSwapBuffers(对于 OpenGL)和 vkQueuePresentKHR(对于 Vulkan)。

eglSwapBuffer 事件的屏幕截图。
图 1. 两次 eglSwapBuffer 事件之间的时间。


vkQueuePresentKHR 事件的屏幕截图。
图 2. 两次 vkQueuePresentKHR 事件之间的时间。

此衡量值是对总 CPU 时间的估计,但不一定代表活跃 CPU 时间。例如,在 GPU 密集型应用中,CPU 可能会等待 GPU 完成其工作,然后再提交新帧。当 dequeueBuffereglSwapBuffer(对于 OpenGL)或 vkQueuePresent(对于 Vulkan)事件占用大部分 CPU 时间时,通常会发生这种情况。等待时间包含在总 CPU 时间中,但不包含在有效 CPU 时间中。

一张屏幕截图,显示了 dequeueBuffer 和 eglSwapBuffer 事件期间的大量空闲时间。
图 3.dequeueBuffereglSwapBuffer 事件期间,大量 CPU 处于空闲状态。

有效 CPU 时间

有效 CPU 时间是指 CPU 在运行应用代码时未处于空闲状态的时间。

如需衡量有效 CPU 时间,请查看 CPU 事件正上方的运行切片。统计两个帧提交事件之间处于 Running 状态的所有轨迹部分。确保您包含工作线程。

一张屏幕截图,显示了两个时间段的 CPU 时间,可用于衡量有效 CPU 时间。
图 5. 可用于衡量有效 CPU 时间的两个 CPU 时间段。


屏幕截图:一个多线程应用,其中主线程处于空闲状态,而其他线程正在工作。
图 6. 主线程处于空闲状态,但有其他工作线程的多线程应用。

衡量有效 CPU 时间的另一种方法是查看 CPU 轨道中的应用切片。这些切片表示 CPU 何时在运行,它们与“正在运行”切片相对应。

一张屏幕截图,显示了与 CPU 轨道匹配的固定线程的运行状态。
图 7. 固定线程的运行状态与 CPU 轨道一致。

为了帮助识别应用 slice,您可以向应用添加 ATrace 标记。这会在系统分析器的 CPU 轨道中显示这些标记。

屏幕截图:显示在 CPU 轨道上的 ATrace 切片。
图 8. CPU 轨道上显示的 ATrace 切片。

估计 GPU 帧时间

如需估算 GPU 帧时间,您可以在系统分析器中使用 GPU 切片或 GPU 计数器。使用 GPU 切片时,估计值会更准确。

GPU 切片

如果系统分析器具有 GPU 切片信息,您可以通过测量应用在处理与单个帧关联的任务上花费的总时间,来获得非常准确的 GPU 帧时间信息。

Mali 设备

在 Mali 设备上,GPU slice 具有 fragment、non-fragment 和偶尔出现的 supplementary non-fragment 轨道。对于不太复杂的帧,fragment 和非 fragment 工作是按顺序进行的,因此可以通过查找活跃 GPU 工作之间的间隙来区分一个帧的工作与另一个帧的工作。

或者,如果您熟悉提交给 GPU 的工作,则可以通过识别提交的渲染通道的模式来了解帧的开始和结束时间。

按顺序执行多个帧的屏幕截图。
图 9. 按顺序执行多个帧。
一张屏幕截图,其中 AGI 放大显示了单个帧的工作。
图 10. 放大显示单个帧的工作。

对于 GPU 工作流程并行化程度更高的应用,您可以在每个切片的选择窗格中查找具有相同 submissionID 的所有帧,从而获取 GPU 帧时间。

对于基于 Vulkan 的应用,可以使用多次提交来合成帧。使用 Vulkan 事件轨道跟踪提交 ID,该轨道包含每次提交的切片。选择提交切片后,系统会突出显示与该提交对应的所有 GPU 活动切片。

一张屏幕截图,显示了并行化的 GPU 工作负载,其中一个帧的工作可以与另一个帧的工作重叠。
图 11. 一种并行化 GPU 工作负载,其中一个帧的工作可以与另一个帧的工作重叠。


针对某个帧选择的多个 Vulkan 事件的屏幕截图。
图 12. 为帧选择了多个 Vulkan 事件。

Adreno 设备

在 Adreno 设备上,GPU slice 会显示在 GPU Queue 0 轨道中,并且始终按顺序表示,因此您可以查看表示帧的渲染通道的所有 slice,并使用它们来衡量 GPU 帧时间。

按顺序执行多个帧的屏幕截图。
图 13. 按顺序执行多个帧。
一张屏幕截图,其中 AGI 放大显示了一个具有多个渲染通道的帧。
图 14. 放大了具有多个渲染通道的帧。

与之前描述的 Mali 场景类似:如果应用使用的是 Vulkan,Vulkan 事件轨道会提供有关提交以执行帧的工作的信息。如需突出显示渲染通道,请点击与帧关联的 Vulkan 事件切片。

基于 Vulkan 的应用的屏幕截图,其中选择了帧的 Vulkan 事件。
图 15.基于 Vulkan 的应用,其中选择了帧的 Vulkan 事件。

在某些情况下,由于应用严重受 GPU 限制,因此 GPU 帧边界更难区分。在这些场景中,如果您熟悉提交给 GPU 的工作,则可以识别渲染通道的执行模式,并根据该信息确定帧边界。

一张 GPU 绑定程度很高的应用的屏幕截图,其中包含有助于识别帧边界的渲染通道模式。
图 16. 具有渲染通道模式的 GPU 密集型应用,有助于识别帧边界。

GPU 计数器

如果轨迹中没有 GPU 切片信息,您可以使用 GPU 计数器轨道来估算 GPU 帧时间。

Mali 设备

在 Mali 设备上,您可以使用 GPU 利用率轨道来估计非 GPU 密集型应用的 GPU 帧时间。如果应用对 GPU 的需求不高,则 GPU 活动会定期出现高低变化,而不是持续处于高活动状态。如需使用 GPU 利用率轨道估算 GPU 帧时间,请测量轨道中高活动时间段的持续时间。

Mali 设备上 GPU 利用率和 GPU 队列轨道的屏幕截图。
图 17. Mali 设备上的 GPU 利用率和 GPU 队列轨道。

如果应用对 GPU 的需求较高,GPU 利用率可能会一直非常高。在这种情况下,您可以使用fragment 队列利用率非 fragment 队列利用率轨道来监控 GPU 活动并估计 GPU 帧时间。通过查找片段非片段轨道中的模式,您可以大致估计帧的边界位置,并使用该位置来测量 GPU 帧时间。

包含 fragment 轨道和非 fragment 轨道的屏幕截图。
图 18. fragment非 fragment 轨道。

Adreno 设备

在 Adreno 设备上,如果应用不是 GPU 密集型应用,您可以按照上一部分中介绍的 Mali 设备上的方式来估算 GPU 帧时间。

Adreno 设备上 GPU 利用率百分比和 GPU 队列轨道图的屏幕截图。
图 19. Adreno 设备上的 GPU 利用率百分比和 GPU 队列轨迹。

如果应用对 GPU 的依赖程度较高,并且应用始终保持较高的 GPU 利用率百分比,您可以使用 Vertex 指令/秒片段指令 / 秒轨道来估计 GPU 帧时间。通过查找这些轨道活动级别的模式,您可以大致估计帧的边界,并使用该边界来测量 GPU 帧时间。

Vertex 说明 / 第二轨道轨道的屏幕截图。
图 20. 每秒顶点指令数轨道。

其他轨道可能提供类似信息:

  • 每秒着色顶点数
  • 每秒阴影处理的 fragment 数
  • 时间着色顶点百分比
  • 时间着色片段百分比