【发布时间】:2012-12-29 19:54:32
【问题描述】:
我们偶然发现了 Quartz Events 的性能问题,更具体地说是 CGEventPost:在 GPU 负载过重时,CGEventPost 可能会阻塞。我们创建了a small benchmark application to demonstrate the issue。这个应用程序只是一个创建、发布和发布事件的循环。
您可以在下面看到运行应用程序的结果。第一次运行是在空闲系统上。第二次运行是使用 FurMark(GPU 压力测试),表盘尽可能地向上转动。
- Inner 是内部循环所花费的时间,基本上只是使用 Quartz Events 创建、发布和发布事件。
- Outer 是我们的程序等待唤醒(睡眠)的时间。应该接近我们睡觉的时间,但如果系统处于压力之下,它可能会延迟。
- 发布是事件发布所需的时间。
18:58:01.683 EventPerformance[4946:707] Measurements: (outer should be close to 10)
18:58:01.684 EventPerformance[4946:707] inner (ms): 0.04, outer (ms): 11.02, CGEventPost (ms): 0.03
18:58:01.684 EventPerformance[4946:707] inner (ms): 0.04, outer (ms): 11.02, CGEventPost (ms): 0.03
18:58:01.685 EventPerformance[4946:707] inner (ms): 0.07, outer (ms): 10.26, CGEventPost (ms): 0.03
18:58:01.685 EventPerformance[4946:707] inner (ms): 0.06, outer (ms): 10.85, CGEventPost (ms): 0.05
18:58:01.686 EventPerformance[4946:707] inner (ms): 0.07, outer (ms): 10.41, CGEventPost (ms): 0.04
18:58:01.686 EventPerformance[4946:707] inner (ms): 0.04, outer (ms): 10.39, CGEventPost (ms): 0.03
18:58:01.686 EventPerformance[4946:707] inner (ms): 0.05, outer (ms): 11.02, CGEventPost (ms): 0.03
18:58:01.687 EventPerformance[4946:707] inner (ms): 0.03, outer (ms): 10.67, CGEventPost (ms): 0.03
18:58:01.687 EventPerformance[4946:707] inner (ms): 0.08, outer (ms): 10.09, CGEventPost (ms): 0.05
18:58:01.688 EventPerformance[4946:707] Averages: (outer should be close to 10)
18:58:01.688 EventPerformance[4946:707] avg inner (ms): 0.05, avg outer (ms): 10.64, avg post (ms): 0.03
在这里我们可以看到发布事件平均需要大约 0.03 毫秒。此外,线程似乎在 0.5ms 左右被唤醒为时已晚。 CGEventPost 中没有峰值。
19:02:02.150 EventPerformance[5241:707] Measurements: (outer should be close to 10)
19:02:02.151 EventPerformance[5241:707] inner (ms): 0.03, outer (ms): 10.23, CGEventPost (ms): 0.02
19:02:02.151 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 10.54, CGEventPost (ms): 0.02
19:02:02.151 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 11.01, CGEventPost (ms): 0.01
19:02:02.152 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 10.74, CGEventPost (ms): 0.01
19:02:02.152 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 10.20, CGEventPost (ms): 0.01
19:02:02.152 EventPerformance[5241:707] inner (ms): 10.35, outer (ms): 11.01, CGEventPost (ms): 10.35
19:02:02.152 EventPerformance[5241:707] inner (ms): 0.03, outer (ms): 10.02, CGEventPost (ms): 0.02
19:02:02.153 EventPerformance[5241:707] inner (ms): 58.90, outer (ms): 10.11, CGEventPost (ms): 58.90
19:02:02.153 EventPerformance[5241:707] inner (ms): 0.03, outer (ms): 10.12, CGEventPost (ms): 0.02
19:02:02.153 EventPerformance[5241:707] Averages: (outer should be close to 10)
19:02:02.371 EventPerformance[5241:707] avg inner (ms): 7.71, avg outer (ms): 10.44, avg post (ms): 7.71
当系统处于繁重的 GPU 负载下时,发布事件可能需要(峰值)毫秒而不是微秒。在极端 GPU 压力(有时似乎在等待 GPU 完成一些工作后再返回。我们的线程仍然正常调度,没有明显的延迟/尖峰(外部)。
感谢任何想法。
【问题讨论】:
-
在提交大量 OpenCL 工作时,我在 Windows(我知道您使用的是 osx)中看到了更糟糕的效果:所有 GPU 绘图都会慢得像爬行一样。就好像 GPU 没有优先级或波前有多早的概念。
-
尝试使用 Instruments 对其进行分析以查看减速发生的位置。
-
您运行此程序的计算机是什么类型的显卡?集成、集成+离散,还是离散?看看您是否在具有不同显卡配置的系统上运行不同的行为会很有趣。
-
似乎两个程序都在争夺锁定的资源。将 gdb 与您的代码一起使用以逐步执行 CGEventPost,检查调用了哪些系统调用以及它是否进入了一些互斥锁。使用带有 FurMark 的 dtruss(gdb 在那里会更难使用)并检查是否调用了相同的系统调用。这可以让你知道正在发生的事情。
-
OSX 的时间片是 10 毫秒;唯一的异常是 60 毫秒的尖峰。
标签: macos core-graphics mouseevent quartz-graphics