3

我正在尝试为 MacOS 编写一个简单的游戏循环。我在 GLFW、SDL 和 MacOS 游戏端口等库中找到的用于 DOOM、Quake、Handmade Hero的事件轮询nextEventMatchingMask解决方案是使用API。我对事件轮询的延迟感兴趣:

t0 = mach_absolute_time();
NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny
                                    untilDate:nil
                                       inMode:NSDefaultRunLoopMode
                                      dequeue:YES];
t1 = mach_absolute_time();
latency=t1-t0

我运行的实验(源代码)包括打开一个 Cocoa MacOS 窗口和“随机”生成鼠标和键盘事件。我在此类实验中获得的前 1000 个事件的典型延迟数如下所示

典型延迟

# latency percentiles in milliseconds
:       0%        5%       10%       15%       20%       25%       30%       35%
: 0.033830  0.047655  0.060302  0.071263  0.073450  0.075871  0.079204  0.083330
:      40%       45%       50%       55%       60%       65%       70%       75%
: 0.093038  0.107813  0.134466  0.143095  0.180434  0.334789  0.448111  0.500118
:      80%       85%       90%       95%      100%
: 0.524535  0.583159  0.648065  0.719931 36.567810

请注意,前 25% 的延迟超过半毫秒。即使没有可用的事件(图表上的零),我们也可以获得超过一毫秒的延迟(参见第 600 个事件附近浮动的零)。更糟糕的是,这是我在 Macbook 没有太多工作时观察到的典型情况:只有一个终端和测试程序。当更多应用程序运行时,情况会变得更糟。

我想知道如果在 MacOS 应用程序中可用,是否有更有效的方法来获取下一个(鼠标/键盘)事件。我是否缺少使nextEventMatchingMask通话更高效的技巧?

可以在此处找到运行此测试并生成类似上述图的源代码:https ://github.com/laurolins/cocoa_poll_events_latency

(更新)按照爸爸在评论中提出的想法,我在没有任何鼠标/键盘移动的情况下进行了测试。以下是延迟百分位数:

# 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.15 毫秒以发现没有生成事件的想法感觉不对!

(更新 2)刚刚对在 ubuntu 上运行的gzdoomSDL_EventPollMessagePump调用进行计时,我得到的延迟分布看起来好多了:

 #       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 上获取下一个键盘/鼠标事件的速度不仅是我的测试代码。

4

0 回答 0