轮询下一个事件的延迟(如果在MacOS上可用)
我正在尝试为MacOS编写一个简单的游戏循环。我在诸如GLFW、SDL和MacOS游戏端口等库中找到的DOOM、Quake和Handmade Hero的事件轮询解决方案是使用轮询下一个事件的延迟(如果在MacOS上可用),macos,cocoa,latency,game-loop,peekmessage,Macos,Cocoa,Latency,Game Loop,Peekmessage,我正在尝试为MacOS编写一个简单的游戏循环。我在诸如GLFW、SDL和MacOS游戏端口等库中找到的DOOM、Quake和Handmade Hero的事件轮询解决方案是使用NextEventMachingmaskAPI。我对事件轮询的延迟感兴趣: 我运行的实验()包括打开Cocoa MacOS窗口并“随机”生成鼠标和键盘事件。在这样的实验中,我得到的前1000个事件的典型延迟数如下所示 请注意,前25%的延迟超过半毫秒。即使没有可用的事件(图表上的零),我们也可以获得超过一毫秒的延迟(参见第
NextEventMachingmask
API。我对事件轮询的延迟感兴趣:
我运行的实验()包括打开Cocoa MacOS窗口并“随机”生成鼠标和键盘事件。在这样的实验中,我得到的前1000个事件的典型延迟数如下所示
请注意,前25%的延迟超过半毫秒。即使没有可用的事件(图表上的零),我们也可以获得超过一毫秒的延迟(参见第600个事件附近的零浮动)。更糟糕的是,这是我观察到的典型情况,当时我的Macbook没有太多的功能:只有一个终端和测试程序。当更多的应用程序运行时,情况会变得更糟
如果MacOS应用程序中有下一个(鼠标/键盘)事件,我想知道是否有更有效的方法来获取该事件。是否有一个技巧让nexteventmachingmask
调用更有效
可以在此处找到运行此测试并生成类似于上面的绘图的源代码:
(更新)根据评论中提出的想法,我在没有任何鼠标/键盘移动的情况下运行了测试。以下是延迟百分比:
# latency without any keyboard/mouse event in milliseconds
: 0% 5% 10% 15% 20% 25%
: 0.04029500 0.07617675 0.07908070 0.08556100 0.10188940 0.12956500
: 30% 35% 40% 45% 50% 55%
: 0.13832200 0.14023150 0.14802140 0.15003550 0.15045250 0.15088950
: 60% 65% 70% 75% 80% 85%
: 0.15125000 0.15162535 0.15190300 0.15235550 0.15313200 0.15972645
: 90% 95% 100%
: 0.16802250 0.21194335 35.93352900
等待.15毫秒以发现没有生成任何事件的想法感觉不正确
(更新2)刚刚对ubuntu上运行的所有SDL\u EventPoll
和MessagePump
调用进行了计时,我得到的延迟分布看起来好多了:
# 0% 5% 10% 15% 20% 25% 30%
:0.00095100 0.00186075 0.00215500 0.00226400 0.00234180 0.00241500 0.00255900
: 35% 40% 45% 50% 55% 60% 65%
:0.00289495 0.00652280 0.00712510 0.00749900 0.00770290 0.00807660 0.00888870
: 70% 75% 80% 85% 90% 95% 100%
:0.00897200 0.00905000 0.00931060 0.01374225 0.01728800 0.03256290 0.23016000
而在MacOS上,gzdoom也在与
nextEventMatchingMask
(数百微秒的延迟数)的慢度作斗争。结论:不仅是我的测试代码在MacOS上获取下一个键盘/鼠标事件的速度很慢。您可以通过缓存IMP
的nexteventmachingmask:untilDate:inMode:dequeue:
方法并直接调用该方法来弥补一点额外的性能,消除objc\u msgSend
调用。您可能希望使用自定义运行循环模式(只是系统框架不太可能使用的字符串),而不是NSDefaultRunLoopMode
。后者允许其他输入源和定时器触发。并且,为了确保这一点,请查看是否有影响。尝试将掩码设置为您关心的事件?更新测试以屏蔽感兴趣的事件,设置自定义运行循环模式,并禁用AppNap。延迟分布似乎在相同的范围内。我的预期可能与此不符,但我预期延迟会小得多。我在考虑windows()上的PeekMessage
API调用。我显示了在nextEventMachingeEventTask:until:Date:inMode:dequeue
中总共花费了119ms,当时我没有按那么多键,而是单击并移动鼠标。如果我没有执行任何事件(没有鼠标移动、单击或键盘活动),我会看到:
# latency without any keyboard/mouse event in milliseconds
: 0% 5% 10% 15% 20% 25%
: 0.04029500 0.07617675 0.07908070 0.08556100 0.10188940 0.12956500
: 30% 35% 40% 45% 50% 55%
: 0.13832200 0.14023150 0.14802140 0.15003550 0.15045250 0.15088950
: 60% 65% 70% 75% 80% 85%
: 0.15125000 0.15162535 0.15190300 0.15235550 0.15313200 0.15972645
: 90% 95% 100%
: 0.16802250 0.21194335 35.93352900
# 0% 5% 10% 15% 20% 25% 30%
:0.00095100 0.00186075 0.00215500 0.00226400 0.00234180 0.00241500 0.00255900
: 35% 40% 45% 50% 55% 60% 65%
:0.00289495 0.00652280 0.00712510 0.00749900 0.00770290 0.00807660 0.00888870
: 70% 75% 80% 85% 90% 95% 100%
:0.00897200 0.00905000 0.00931060 0.01374225 0.01728800 0.03256290 0.23016000