MacGamingFixes
macgamingfixes / wi-fi без задержек

wi-fi без задержек

часть macgamingfixes. та же статья есть в приложении, рядом с переключателем.

чип wi-fi в mac может придерживать пакеты до 25 мс ради экономии энергии. он перестаёт это делать, когда какой-нибудь сокет запрашивает обслуживание реального времени. wine его не запрашивает, поэтому запрашивает этот фикс.

симптом

по wi-fi от четверти до половины игровых пакетов приходят с опозданием на 10–25 мс даже на первом переходе до роутера. медленный режим появляется и пропадает на десятки секунд.

причина

энергосбережение чипа придерживает трафик до жёсткого потолка около 25 мс, пока ни один сокет на интерфейсе не несёт класс реального времени (SO_NET_SERVICE_TYPE). потолок одинаков при 16 и при 256 пакетах в секунду. эффект действует на весь интерфейс: один помеченный сокет ускоряет все потоки.

замеры

udp-поток 64 гц до роутера, от сети, 5 ггц, по шесть чередующихся раундов на класс.

класс обслуживаниямедианаопоздали > 15 мс
best effort8.7 мс25 %
responsive data10.7 мс17 %
interactive video3.8 мс1.2 %
voice3.8 мс4.4 %
медиана до роутерадо8.7 мспосле3.8 мс

та же проба из winsock-сокета в тестовой бутылке: без фикса медиана 10.5–14.4 мс и 20–45 % опоздавших, с фиксом 4.0–4.4 мс и 0–10 %.

фикс

wine создаёт все сокеты windows внутри wineserver, поэтому один перехват покрывает все игры в бутылке. внедрённая библиотека перехватывает socket() и помечает каждый udp-сокет как interactive video.

wineserver_fix.c
static int my_socket(int domain, int type, int protocol) {
    int fd = socket(domain, type, protocol);
    if (fd >= 0 && udp_service && type == SOCK_DGRAM)
        setsockopt(fd, SOL_SOCKET, SO_NET_SERVICE_TYPE,
                   &udp_service, sizeof udp_service);
    return fd;
}

что меняется на диске

ограничения