DirectInput8 EnumDevices иногда очень медленно

Иногда (примерно в 50% запусков) EnumDevices возвращается через 5-10 секунд. Обычно это почти мгновенно. Других сообщений о подобном поведении я не нашел.

Когда все так медленно, можно профилировать, наблюдая за stdout :) Это:

std::cout << "A";
directInput8Interface->EnumDevices(DI8DEVCLASS_GAMECTRL, MyCallback, NULL, DIEDFL_ATTACHEDONLY);
std::cout << "C";

...

BOOL CALLBACK MyCallback(LPCDIDEVICEINSTANCE, LPVOID)
{
    std::cout << "B";
    return DIENUM_CONTINUE;
}

Кажется, зависает в случайной точке через перечисление устройств - иногда это будет до того, как callback будет вызван вообще, иногда после пары, а иногда будет после последнего вызова к нему.

Это явно упрощенный фрагмент кода; На самом деле я использую библиотеку ввода OIS ( http://sourceforge.net/projects/wgois/ ), так что для контекста, пожалуйста, смотрите полный источник здесь:

http://wgois.svn.sourceforge.net/viewvc/wgois/ois/trunk/src/win32/Win32InputManager.cpp?revision=39&view=markup

Там, похоже, не происходит ничего особенно фруктового, но, возможно, причиной может быть что-то в их инициализации - я недостаточно знаю о DI8, чтобы это заметить.

Буду очень признателен за любые идеи о том, почему это может быть так медленно!

РЕДАКТИРОВАТЬ:

Мне удалось поймать зависание в файле трассировки etl и проанализировать его в анализаторе производительности Windows. Похоже, что EnumDevices в конце концов звонит DInput8.dll!fGetProductStringFromDevice, который звонит HIDUSB.SYS!HumCallUSB, который звонит KeWaitForSingleObject и ждет. В 9 случаях из 10 (буквально - в трассировке 10 выборок) это возвращается очень быстро (по 324 мкс каждый), при этом готовый стек вызовов содержит usbport.sys!USBPORT_Core_iCompleteDoneTransfer, за которым следует HIDUSB.SYS!HumCallUsbComplete, что выглядит вполне нормально.

Но 1 раз из 10 на возврат уходит почти ровно 5 секунд. В готовящемся стеке вызовов есть ntkrnlmp.exe!KiTimerExpiration вместо функции HIDUSB.SYS. Я предполагаю, что все это указывает на то, что драйвер HIDUSB.SYS опрашивает устройства асинхронно с тайм-аутом в 5 секунд, и иногда он дает сбой и достигает этого тайм-аута.

Я не знаю, связан ли этот сбой с каким-то конкретным устройством (у меня есть несколько USB HID) или он случайный - это трудно проверить, потому что это не всегда происходит. Опять же, любая информация, которую кто-либо может мне дать, будет оценена по достоинству, хотя я не питаю никакой надежды на то, что Microsoft исправит это в ближайшее время, учитывая странную ситуацию, в которой находится DirectInput!

Возможно, мне просто придется начать инициализацию ввода раньше, асинхронно, и принять, что иногда будет 5-секундная задержка, прежде чем пользователь сможет ввести данные.


person Ben Hymers    schedule 10.06.2012    source источник


Ответы (7)


Я тоже столкнулся с этим, в основном как конечный пользователь, но это чертовски раздражало меня в течение многих лет. Я не осознавал, что это была проблема, пока не столкнулся с ней в проекте с открытым исходным кодом и не смог ее отладить.

Оказывается, это был мой USB-ЦАП для наушников (Objective DAC от Massdrop), он устанавливает драйвер: wdma_usb.inf_amd64_134cb113911feba4\wdma_usb.inf для идентификатора экземпляра устройства USB\VID_262A&PID_1048&MI_01\7&F217D4F&0&0001, а затем отображается в диспетчере устройств в разделе «Звуковые, видео и игровые контроллеры» как: ODAC-revB USB DAC и в разделе «Устройства интерфейса пользователя». как: USB Input Device и HID-compliant consumer control device.

Я понятия не имею, что делают записи HID, но... Когда они включены и этот ЦАП установлен в качестве устройства вывода звука, IDirectInput8_CreateDevice и EnumDevices мучительно медленны. Отключение записи «USB-устройство ввода», похоже, не вызывает никаких негативных последствий и полностью решает мою проблему.

Изменение аудиовыхода с ЦАП на что-либо еще также странным образом решило проблему.

Это было настолько плохо, что сделало диалоговое окно конфигурации геймпада joy.cpl непригодным для использования, зависшим и, в конечном итоге, аварийным.

Я хотел, чтобы это был просто комментарий, но у меня недостаточно представителей для этого, и это почти единственное место в Интернете, где описывается эта проблема, хотя, надеюсь, это поможет кому-то еще однажды!

person DaFox    schedule 06.11.2016
comment
Очень интересно! Спасибо! Я так и не докопался до сути этого и никогда не сталкивался с этим ни на одной другой машине, поэтому я предположил, что это устройства с плохим поведением или что-то в этом роде, и ваш отчет предполагает то же самое! Приятно знать, что я не единственный, на кого это влияет! - person Ben Hymers; 06.11.2016
comment
Обновление: иногда устанавливался другой драйвер wdma_usb.inf, который также имел ту же проблему. Однако эта проблема больше не возникает на моем новом ПК. Старая была машина Intel Haswell. - person DaFox; 04.01.2020
comment
Ты спаситель. У меня была эта проблема почти 10 лет. Отключил несколько неясных записей USB-устройств ввода, и проблема исчезла, с 10 секунд до 200 мс. Хотя я добавлю, что все эти устройства показали input.inf; ни у кого ничего не было с wdma. У меня также был Objective DAC (до того, как он сломался), но не от Massdrop. Я думаю, что JDS Labs сейчас продает их более новые версии, которые предположительно ломаются реже: blog.jdslabs.com/2015/05/releasing-odac-revb Я попытаюсь бросить им это, может быть, мы узнаем что-то интересное. - person Zyl; 19.04.2020
comment
Немного дополнительного чтения, просто чтобы мы могли получить всю эту информацию, ссылаясь друг на друга: github.com/ godotengine/godot/issues/20566 github.com/pygame/pygame/issues/2173 - person DaFox; 20.06.2021

Я была такая же проблема. У меня клавиатура Corsair K65 LUX RGB. Я обновил CUE, и, кажется, проблема устранена.

person Matheus Ronfim    schedule 10.09.2018

У меня такая же проблема с клавиатурой Corsair K55. Смена клавиатуры USB-порта устраняет проблему на некоторое время, но позже она возвращается. Так что, похоже, проблема с глючными драйверами.

person ManuTOO    schedule 23.12.2017
comment
Интересно, у меня такая же проблема, и в настоящее время у меня есть клавиатура Corsair K66. - person Greg; 07.07.2020

Как указал DaFox, вероятной причиной является включение определенных драйверов устройств. Я связался со службой поддержки JDS Labs (которая продает одно устройство, на которое устанавливается один такой драйвер), и они любезно указали, что основной причиной на самом деле является ошибка в Windows (а не установленный драйвер), и они фактически предоставляют решение на своей странице устранения неполадок. . См. Games hang or experience loading delays, в котором явно упоминается VID_262. Отключение этого драйвера устраняет проблему без явных побочных эффектов (при условии, что это единственный драйвер, вызывающий ошибку). Что же касается того, что именно не так в Windows, то здесь есть драконы.

Поэтому я предполагаю, что решение (для пользователей) состоит в том, чтобы очистить все страницы устранения неполадок и часто задаваемых вопросов для всех устройств, которые вы когда-либо подключали к своей системе, и посмотреть, есть ли упоминания о задержках / задержках, вызванных драйвером.

Как разработчик программного обеспечения, вы, вероятно, захотите сравнить время выполнения затронутого кода и любезно сообщить пользователю, что что-то не так с конфигурацией его системы, и где искать, как это исправить, если оно неоправданно долгое.

person Zyl    schedule 19.04.2020

Та же проблема с клавиатурой Corsair K70. Быстрое повторное подключение клавиатуры исправляет это до следующего раза. Обычно происходит после того, как некоторые устройства DirectInput удаляются из системы или переходят в спящий режим.

person user10183249    schedule 05.08.2018

Это мучило меня как разработчика и моего друга как пользователя в течение многих лет. Все игры, использующие DInput, SDL SDL_INIT_JOYSTICK или что-то еще в зависимости от этого, очень долго инициализировались.

Это было вызвано неисправным драйвером ЦАП, и, как указал DaFox, отключение соответствующего устройства ввода USB решило проблему. Хотя он помечен другим производителем, идентификаторы поставщиков совпадают.

Идентификатор оборудования устройства — USB\VID_262A&PID_9023&REV_0001&MI_00.

person Domi    schedule 27.07.2020

Та же проблема возникает с клавиатурой Steelseries Apex 7. Отключение и повторное подключение этой клавиатуры избавило от 3 зависаний (по 10 секунд каждое) при перечислении USB-устройств.

person STenyaK    schedule 27.01.2021