【问题标题】:Under what conditions does Metal shader code "crash?"金属着色器代码在什么情况下会“崩溃”?
【发布时间】:2015-08-12 00:59:30
【问题描述】:

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

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

没有错误报告给控制台。

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

【问题讨论】:

  • 我正在使用计算内核,我也经常崩溃。无论如何,xcode 没有帮助。我注释掉代码,直到它工作,然后添加回来。花费大量时间。金属游乐场会很棒。快速测试少量代码。
  • 使用它一段时间后,它似乎主要是iOS故障恢复系统的副作用(我在OS X上没有遇到很多这些问题)。我已将大多数崩溃缩小为着色器执行速度太慢(当 FPS 低于 1 时 iOS 似乎会自动使应用程序崩溃,以防止应用程序使整个设备崩溃)或当我访问无效的内存区域时(iOS 应用程序是,毕竟,沙盒)。现在,如果这些系统能够真正与 Metal 前端沟通驱动程序已崩溃,这样对 API 的调用就会报告实际错误,那就太好了。
  • 我为 c++ 设置了一个测试项目来调试代码。这样语法高亮和调试会好很多。我认为有很多循环的大着色器需要很长时间。然后它崩溃了,就像你的一样
  • 我有一个带有三个嵌套 for 循环的着色器,它们编译得很好,但在运行时拒绝链接,更不用说在设备上运行了。着色器函数的大小/嵌套分支的数量似乎有一些限制,但我找不到关于这些限制的任何细节(显然,Xcode 在这里根本没有帮助)。这只是反复试验。
  • iOS 上当前的 Metal 实现显然是为游戏图形和交互式应用程序设计的,而不是为硬核计算而设计的。另一方面,在 OS X 上,它会无限期地消耗所有 GPU 资源并锁定系统(至少 Windows 在重置 GPU 之前为单个图形命令设置了 3 秒的限制)。跨度>

标签: ios metal


【解决方案1】:

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

【讨论】:

  • 这使得在 iOS 上使用 Metal 来处理任何繁重/可变的计算负载变得非常困难。真的没有抢占选项,所以在不阻塞 GUI 任务的情况下可以继续进行繁重的计算吗?
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2023-02-23
    • 2018-03-24
    • 2012-11-24
    • 2012-12-09
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多