估算 CPU 和 GPU 帧处理时间

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

CPU 时间

在 AGI 中,您可以在系统配置文件的 CPU 轨道中查看总 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 片段。统计处于 Running 状态的两个帧提交事件之间的轨迹的所有部分。确保添加工作线程。

两个 CPU 时间段的屏幕截图,可用于衡量活跃 CPU 时间。
图 5. 两个 CPU 时间段,可用于衡量活动 CPU 时间。


一张屏幕截图,显示了主线程处于空闲状态时,具有其他工作线程的多线程应用。
图 6. 在主线程空闲时具有其他工作线程的多线程应用。

测量活动 CPU 时间的另一种方法是查看 CPU 轨道中的应用 slice。这些 slice 表示 CPU 何时正在运行,并且与 Running slice 相对应。

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

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

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

估算 GPU 帧时间

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

GPU 切片

如果系统性能分析器有 GPU slice 信息,您可以通过衡量应用处理与单个帧关联的任务所花费的总时间,获得非常准确的 GPU 帧时间信息。

Mali 设备

在 Mali 设备上,GPU slice 具有 fragmentnon-fragment 和有时的supplementary non-fragment 轨道。对于不太复杂的帧,fragment 和非 fragment 工作是顺序的,因此可以通过查找 GPU 工作之间的间隔来区分一个帧的工作与另一个帧的工作。

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

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

对于 GPU 工作流程并行度更高的应用,您可以通过在每个 Slice 的 Selection 窗格中查找具有相同 submissionID 的所有帧来获取 GPU 帧时间。

对于基于 Vulkan 的应用,可以使用多次提交来组合帧。使用 Vulkan 事件轨道(其中包含每个提交内容的 slice)跟踪提交内容 ID。选择提交内容 slice 会突出显示与提交内容对应的所有 GPU 活动 slice。

并行 GPU 工作负载的屏幕截图,其中一个帧的工作可能会与另一个帧的工作重叠。
图 11. 并行 GPU 工作负载,其中一个帧的工作可以与另一个帧的工作重叠。


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

Adreno 设备

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

依序执行多个帧的屏幕截图。
图 13. 按顺序执行多个帧。
一张屏幕截图,其中 AGI 放大了包含多个渲染传递的帧。
图 14. 放大了包含多个渲染传递的帧。

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

基于 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 帧时间。通过在 fragmentnon-fragment 轨道中查找模式,您可以粗略估算帧的边界,并据此测量 GPU 帧时间。

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

Adreno 设备

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

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

如果应用对 GPU 的依赖程度更高,并且 GPU 利用率始终较高,您可以使用顶点指令/秒片段指令 / 秒轨道来估算 GPU 帧时间。通过查找这些轨道的活动水平中的模式,您可以大致估算出帧的边界,并据此衡量 GPU 帧时间。

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

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

  • 每秒着色顶点数
  • 每秒阴影 Fragment 数
  • 阴影顶点所占的时间百分比
  • 着色 fragment 所用时间百分比