如何测量Metal上的GPU时间?

时间:2017-07-11 13:06:00

标签: profiling metal

我想看看以编程方式我的应用程序的一部分GPU时间消耗在macOS和iOS上的时间。在OpenGL和D3D上,我可以使用GPU计时器查询对象。我搜索过,找不到类似金属的东西。如何在不使用乐器的情况下测量金属上的GPU时间等。我正在使用Objective-C。

2 个答案:

答案 0 :(得分:3)

这种方法存在一些问题:

1)你真的想知道大多数时候命令缓冲区内的GPU端延迟是什么,而不是往返CPU。这可以更好地测量为运行20个着色器实例和10个着色器实例之间的时间差。然而,该方法可能会增加噪声,因为误差是与两次测量相关的误差的总和。

2)等待完成导致GPU在停止执行时倒计时。当它再次开始重新启动时,时钟处于低功耗状态,并且可能需要相当长的时间再次出现,从而扭曲您的结果。这可能是一个严重的问题,并且可能会低估您在基准测试与实际测试中的性能两倍或更多。

3)如果您按计划启动时钟并且已完成停止,但GPU正在忙于运行其他工作,则您的已用时间包括在其他工作负载上花费的时间。如果GPU不忙,则会出现(2)中描述的时钟故障问题。

这个问题比我使用过的大多数基准测试案例都要难得多,而且我做了很多性能测量。

测量这些东西的最佳方法是在设备性能监视器计数器上使用,因为它可以直接衡量正在发生的事情,使用机器自己的时间概念。我赞成那些报告周期超过挂钟时间的人,因为这往往会淘汰时钟转换,但对此没有普遍的一致意见。 (并非硬件的所有部分都以相同的频率运行,等等。)我会向开发人员工具寻找基于PMC进行测量的方法,如果找不到它们,请询问它们。

答案 1 :(得分:2)

您可以将已调度和已完成的处理程序块添加到命令缓冲区。您可以在每个时间戳中进行比较。有一些延迟,因为这些块是在CPU上执行的,但它应该让你关闭。

使用Metal 2.1,Metal现在提供"事件",它们更像是其他API中的围栏。 (名称MTLSharedEvent已用于同步共享堆内容。)特别是,使用MTLCommandBuffer,您可以编码命令以修改命令缓冲区中特定点的事件值(s) )。然后,您可以使事件获得该值,或者在事件达到目标值时要求异步执行块。

仍存在延迟等问题(如Ian Ollmann所述),但比命令缓冲区调度和完成更精细。特别是,正如Klaas在评论中提到的那样,正在调度的命令缓冲区并不表示它已经开始执行。您可以在命令序列的末尾设置命令以在开头设置事件的值(并使用不同的值),这些命令仅在实际执行时通知。

最后,在iOS 10.3+而不是macOS上,GPUStartTime有两个属性GPUEndTimeecho json_encode($row). "<br>"."<br>"; ,您可以使用这两个属性确定命令缓冲区执行的时间。 GPU。这不应该像其他技术一样受到延迟的影响。