5

我正在开发一个基于 Metal 的应用程序,在某些情况下,正确编译和链接的着色器代码会导致应用程序简单地崩溃而不会引发任何错误。

“崩溃”包括视觉输出的停止(在某些情况下,之前是几个交替帧的短暂停顿),但其他应用程序的其余部分正常运行。Xcode 性能监控实用程序报告 60fps 但 GPU 延迟为 0ms,并且 CPU 端执行继续,对 Metal API 的调用仍然成功完成。

不会向控制台报告任何错误。

这非常难以调试,因为我不知道错误来自着色器代码的何处。如果我知道这实际上应该在什么条件下发生,那将会有所帮助,这样我就可以有一个很好的清单来检查。否则,每当出现这种情况时,我都会在黑暗中拍摄。

4

2 回答 2

2

当您读取或注销 MTLBuffer 的末尾、注销 MTLTexture 的末尾或只是运行时间过长时,GPU 可能会崩溃。有一个看门狗定时器,如果它在几秒钟内没有完成它的工作,它会重置 GPU。GPU 上的工作不是预先安排好的。长时间运行的工作可能会通过阻止执行基本的 GUI 任务来使设备看起来被锁定。如果您有长时间运行的工作负载,则有必要将其拆分为许多较小的内核。要保持界面响应,您应该保持工作负载 < 100 毫秒。为避免视频卡顿,建议使用一致的帧速率。

于 2016-06-18T16:17:13.540 回答
1

由于重金属着色器,我经常发生崩溃,并设法通过限制调度率来修复它。您可以通过测量最后一个“帧”的运行时间来轻松做到这一点,并在每次调度之前按该数量的比率插入等待:

[NSthread sleepFortimeInterval: _lastRunTime*RATIO];
NSDate *startTime = [NSDate date];
... [use Metal shaders] ...
_lastRunTime = -[startTime timeIntervalSinceNow];

我将 RATIO 设置为 1.0。所以它永远不会使用超过 50% 的 gpu。它显然会影响帧速率,但会击败随机崩溃。你可以玩这个比例。好消息是您不必担心在不同产品上限制太多或太少,因为它是运行时的比率。

于 2018-01-18T01:54:39.103 回答