我正在开发基于金属的应用程序,在某些情况下,正确编译和链接的着色器代码会导致应用程序崩溃而不会丢失任何错误。
“崩溃”包括视觉输出的停顿(在某些情况下,前面是几个交替帧的短口吃),但是否则是应用程序其余部分的正常处理。 Xcode性能监控实用程序报告60fps但GPU延迟为0ms,并且CPU端执行仍在继续,对Metal API的调用仍然成功完成。
没有错误报告给控制台。
这是非常难以调试的,因为我没有指出错误来自着色器代码的位置。如果我知道在什么条件下实际应该发生这种情况会有所帮助,这样我就可以有一个很好的清单来检查。否则我只是在黑暗中拍摄。
答案 0 :(得分:2)
当您读取或注销MTLBuffer的末尾,注销MTLTexture的末尾或者只是运行太长时,GPU可能会崩溃。有一个看门狗定时器,如果它在几秒钟内没有完成其工作,它将重置GPU。 GPU上的工作不是预先安排的。通过阻止执行基本GUI任务,长时间运行的工作可能会使设备看起来被锁定。如果您有长时间运行的工作负载,则需要将其拆分为许多较小的内核。为了保持界面响应,您应该保持工作负载< 100毫秒为避免视频卡顿,建议使用一致的帧速率。
答案 1 :(得分:0)
由于重金属着色器,我经常发生崩溃,并通过限制调度率来修复它。您可以通过测量最后一个“帧”的运行时间,并在每个调度之前插入一个等待的数量来轻松地执行此操作:
[NSthread sleepFortimeInterval: _lastRunTime*RATIO];
NSDate *startTime = [NSDate date];
... [use Metal shaders] ...
_lastRunTime = -[startTime timeIntervalSinceNow];
我将RATIO设置为1.0。所以它永远不会使用超过50%的gpu。它显然会影响帧速率,但会击败随机崩溃。你可以玩这个比例。好的一点是你不必担心不同产品上的节流过多或过少,因为它是运行时间的比例。