可绘制延迟,导致稳态延迟

时间:2021-02-18 06:08:53

标签: swift metal

我有一个小小的 Swift 游乐场,它使用 Metal 计算内核在鼠标每次移动时绘制纹理。计算内核运行速度非常快,但由于某种原因,当我开始拖动鼠标时,系统中会产生一些未知的延迟,最终每个鼠标移动事件的结果显示多达 4 帧收到事件后。

我所有的代码都在这里:https://github.com/jtbandes/metalbrot-playground

我将此代码复制到示例应用中,并在鼠标事件处理程序周围添加了一些 os_signpost,以便我可以在 Instruments 中对其进行分析。我看到的是第一个鼠标拖动事件很快完成了它的计算工作,但是“表面排队”事件直到超过一帧之后才会发生。然后,一旦表面排队,它实际上不会在下一个 vsync 显示,而是在下一个 vsync 显示。

第二个鼠标拖动事件的表面在计算完成后立即排队,但现在由于前一帧延迟而卡在等待另一个垂直同步。几帧之后,延迟构建和后面的帧必须等待很长时间才能绘制可用,然后才能进行任何工作。在稳定状态下,我看到事件处理程序和 drawable 最终呈现之间大约有 4 帧的延迟。

  1. 是什么导致了这些初始延迟,我可以做些什么来减少它们?
  2. 是否有一种简单的方法可以防止延迟加重,例如告诉系统自动丢帧?

1 个答案:

答案 0 :(得分:1)

我仍然不知道最初的延迟来自哪里,但我找到了防止延迟复合的解决方案。

事实证明我对鼠标事件做出了错误的假设。鼠标事件可以比屏幕更新更频繁地传送——在我的测试中,鼠标拖动事件之间的间隔通常不到 8 毫秒,有时甚至不到 3 毫秒,而屏幕以 ~16.67 毫秒的间隔更新。所以在每个鼠标拖动事件上渲染场景的想法从根本上是有缺陷的。

解决此问题的一个简单方法是跟踪排队的绘制,如果另一个可绘制对象仍在排队,则不要再次开始绘制。例如,类似于:

for index, branch in enumerate(all_branches):
    leaf_index = branch[-1]
    print(f'Branch: {index}, Path: {branch}')
    print(f'Gin {impurity[leaf_index]} at leaf node {branch[-1]}')
    print(f'Value: {value[leaf_index]}')
    print(f"Decision Rules: {[f'if X[:, {feature[elem]}] <= {threshold[elem]}' for elem in branch]}")
    print(f"---------------------------------------------------------------------------------------\n")
>>>
Branch: 0, Path: [0, 1]
Gin 0.0 at leaf node 1
Value: [[37.  0.  0.]]
Decision Rules: ['if X[:, 3] <= 0.800000011920929', 'if X[:, -2] <= -2.0']
---------------------------------------------------------------------------------------

Branch: 1, Path: [0, 2, 3, 5]
Gin 0.0 at leaf node 5
Value: [[ 0. 32.  0.]]
Decision Rules: ['if X[:, 3] <= 0.800000011920929', 'if X[:, 2] <= 4.950000047683716', 'if X[:, 3] <= 1.6500000357627869', 'if X[:, -2] <= -2.0']
---------------------------------------------------------------------------------------

Branch: 2, Path: [0, 2, 3, 6, 7]
Gin 0.0 at leaf node 7
Value: [[0. 0. 3.]]
Decision Rules: ['if X[:, 3] <= 0.800000011920929', 'if X[:, 2] <= 4.950000047683716', 'if X[:, 3] <= 1.6500000357627869', 'if X[:, 1] <= 3.100000023841858', 'if X[:, -2] <= -2.0']
---------------------------------------------------------------------------------------

Branch: 3, Path: [0, 2, 3, 6, 8]
Gin 0.0 at leaf node 8
Value: [[0. 1. 0.]]
Decision Rules: ['if X[:, 3] <= 0.800000011920929', 'if X[:, 2] <= 4.950000047683716', 'if X[:, 3] <= 1.6500000357627869', 'if X[:, 1] <= 3.100000023841858', 'if X[:, -2] <= -2.0']
---------------------------------------------------------------------------------------

Branch: 4, Path: [0, 2, 4, 9]
Gin 0.375 at leaf node 9
Value: [[0. 1. 3.]]
Decision Rules: ['if X[:, 3] <= 0.800000011920929', 'if X[:, 2] <= 4.950000047683716', 'if X[:, 2] <= 5.049999952316284', 'if X[:, -2] <= -2.0']
---------------------------------------------------------------------------------------

Branch: 5, Path: [0, 2, 4, 10]
Gin 0.0 at leaf node 10
Value: [[ 0.  0. 35.]]
Decision Rules: ['if X[:, 3] <= 0.800000011920929', 'if X[:, 2] <= 4.950000047683716', 'if X[:, 2] <= 5.049999952316284', 'if X[:, -2] <= -2.0']
---------------------------------------------------------------------------------------

相关问题