Задержка опроса следующего события, если доступно на MacOS - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь написать простой игровой цикл для 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

Эксперимент, который я запускаю ( исходный код ), состоит из открытия окна MacOS Cocoa и «случайно»генерирование событий мыши и клавиатуры.Типичные числа задержек, которые я получаю для первых 1000 событий в таком эксперименте, выглядят так:

typical latency

# 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) Только по времени все SDL_EventPoll и MessagePump звонки на gzdoom , работающие на Ubuntu и распределении задержек, которые я получаю, выглядят намного лучше:

 #       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.

...