估算 CPU 和 GPU 帧处理时间

估算 CPU 和 GPU 帧处理时间(帧时间)对于了解应用程序的性能和查找瓶颈至关重要。当您使用 AGI 分析应用程序时,系统分析器会提供可用于估算帧时间跟踪数据。

CPU 时间

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

总 CPU 时间

要测量花费的总 CPU 时间,选择包含连续帧提交事件之间的时间的时间范围。帧提交事件是 eglSwapBuffers(对于 OpenGL)和 vkQueuePresentKHR(对于 Vulkan)。

A screenshot of several eglSwapBuffer events.
图 1. 几个 eglSwapBuffer 事件。


A screenshot of a vkQueuePresentKHR event.
图 2. 一个 vkQueuePresentKHR 事件。

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

A screenshot that displays a large amount of idling during dequeueBuffer and eglSwapBuffer events.
图 3.dequeueBuffereglSwapBuffer 事件期间大量空闲。

活动 CPU 时间

活动 CPU 时间确定 CPU 何时在没有处于空闲状态的情况下运行应用程序代码。

要测量活动 CPU 时间,请查看 CPU 事件正上方的“正在运行”切片。计算两次帧提交事件之间跟踪中所有处于“正在运行”状态的部分。确保您包含工作线程。

A screenshot of two periods of CPU time that can be used to measure the active CPU time.
图 5. 可用于测量活动 CPU 时间的两个 CPU 时间段。


A screesnshot of a multithreaded app that has a working thread while the main thread is idle.
图 6. 一个多线程应用程序,在主线程空闲时具有工作线程。

测量活动 CPU 时间的另一种方法是查看 CPU 轨迹中的应用程序切片。这些切片指示 CPU 何时正在运行,并且与“正在运行”切片相对应。

A screenshot that displays the running state of a pinned thread that matches the CPU track.
图 x. 固定线程的运行状态与 CPU 轨迹匹配。

为了帮助识别应用程序切片,您可以向您的应用程序添加 ATrace 标记。这将在系统分析器的 CPU 轨迹中显示标记。

A screenshot of an ATrace marker in a CPU track.
图 8. CPU 轨迹中的 ATrace 标记。

估算 GPU 帧时间

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

GPU 切片

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

Mali 设备

在 Mali 设备上,GPU 切片具有“片段”、“非片段”以及偶尔的“补充非片段”轨迹。对于不太复杂的帧,片段和非片段工作是顺序的,因此可以通过查找活动 GPU 工作之间的间隙来区分一个帧的工作与另一个帧的工作。

或者,如果您熟悉提交到 GPU 的工作,则识别提交的渲染通道的模式将提供有关帧何时开始和结束的信息。

A screenshot of multiple frames being executed in sequence.
图 9. 多个帧按顺序执行。
A screenshot where AGI is zoomed in on an individual frame’s work.
图 10. 放大到单个帧的工作。

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

对于基于 Vulkan 的应用程序,可以使用多个提交来组合帧。使用“Vulkan 事件”轨迹跟踪提交 ID,该轨迹包含每个提交的切片。选择提交切片将突出显示与提交相对应的所有 GPU 活动切片。

A screenshot of a parallelized GPU workload, where work on one frame can overlap with another.
图 11. 并行化的 GPU 工作负载,其中一个帧的工作可能与另一个帧的工作重叠。


A screenshot of several Vulkan events for a selected frame.
图 12. 选择帧的几个 Vulkan 事件。

Adreno 设备

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

A screenshot of multiple frames being executed in sequence.
图 13. 多个帧按顺序执行。
A screenshot where AGI is zoomed in on a frame with multiple render passes.
图 14. 放大到具有多个渲染通道的帧。

与前面描述的 Mali 方案类似:如果应用程序正在使用 Vulkan,“Vulkan 事件”轨迹提供了有关提交以执行帧的工作的信息。要突出显示渲染通道,请单击与帧关联的“Vulkan 事件”切片。

A screenshot of a Vulkan-based app with Vulkan events for a selected frame.
图 15. 基于 Vulkan 的应用程序,其中包含所选帧的 Vulkan 事件。

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

A screenshot of a heavily GPU bound app with a render pass pattern that helps identify frame boundaries.
图 16. 严重绑定到 GPU 的应用程序,其渲染通道模式有助于识别帧边界。

GPU 计数器

如果跟踪中没有 GPU 切片信息,则可以使用“GPU 计数器”轨迹来估算 GPU 帧时间。

Mali 设备

在 Mali 设备上,您可以使用“GPU 利用率”轨迹来估算非 GPU 密集型应用程序的 GPU 帧时间。当应用程序的 GPU 密集程度较低时,它们具有规律的高 GPU 活动和低 GPU 活动周期,而不是持续的高活动。要使用“GPU 利用率”轨迹估算 GPU 帧时间,请测量轨迹中高活动周期的持续时间。

A screenshot of the GPU utilization and GPU Queue tracks on a Mali device.
图 17. Mali 设备上的 GPU 利用率和 GPU 队列轨迹。

如果应用程序的 GPU 密集程度较高,则可以使用“片段”和“非片段”轨迹来估算 GPU 帧时间。通过查找“片段”和“非片段”轨迹的活动级别中的模式,您可以大致估算帧边界在哪里,并使用它来测量 GPU 帧时间。

A screenshot of fragment and non-fragment tracks.
图 18. 片段非片段 轨迹。

Adreno 设备

在 Adreno 设备上,如果应用程序的 GPU 密集程度不高,则可以像上一节中使用 Mali 设备 一样估算 GPU 帧时间。

A screenshot of the GPU utilization and GPU Queue tracks on an Adreno device.
图 19. Adreno 设备上的 GPU 利用率和 GPU 队列轨迹。

如果应用程序的 GPU 密集程度较高,则可以使用“每秒顶点指令”和“每秒片段指令”轨迹来估算 GPU 帧时间。通过查找这些轨迹的活动级别中的模式,您可以大致估算帧边界在哪里,并使用它来测量 GPU 帧时间。

A screenshot of the Vertex Instructions / Second track.
图 20. 每秒顶点指令 轨迹。

这些其他跟踪可能提供类似的信息

  • 每秒渲染的顶点数量
  • 每秒渲染的片段数量
  • 顶点着色时间百分比
  • 片段着色时间百分比