Производительность хуков WH_CALLWNDPROC резко снижается с Win10 (по сравнению с Win7)? - PullRequest
1 голос
/ 07 мая 2019

Мы находимся в процессе обновления наших рабочих станций до Win10 с Win7.Исследуя сообщения о снижении производительности, я пришел к выводу, что это было вызвано хуком WH_CALLWNDPROC, установленным третьей стороной.

Я пришел к такому выводу на основе результата следующего тестового приложения (сделано в Delphi 10Сиэтл)

procedure TForm3.Button1Click(Sender: TObject);
var
  I: Integer;
  SW : TStopWatch;
begin
  sw := TStopWatch.StartNew;
  for I := 0 to 1000000 do
  begin
    if Combobox1.ItemIndex > 0 then
      Exit;
  end;
  sw.Stop;
  ShowMessage(sw.ElapsedMilliseconds.ToString);
end;

(Для тех, кто не знаком с Delphi, TStopwatch использует API QueryPerformanceFrequency / QueryPerformanceCounter для получения истекшего времени)

Время выполнения для этого метода составляет

  • Win10: 1485 мсек
  • Win7: 4996 мсек

(Примечание. Обе машины работают на совершенно разных аппаратных средствах и их нельзя сравнивать с другими). ​​

Теперь, если я добавлю ловушку перед выполнением того же кода

function MySystemWndProcHook(Code: Integer; wParam: WParam; lParam: LParam): LRESULT; stdcall;
begin
  Result := CallNextHookEx(FHook, Code, wParam, LParam);
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
  FHook := SetWindowsHookEx(WH_CALLWNDPROC, @MySystemWndProcHook, 0, GetCurrentThreadId)
end;

Время выполнения теперь становится:

  • Win10: 19552 мсек (примерно на 1300% больше)
  • Win7: 8682 мсек (примерно на 75% больше)

Теперь, как я уже упоминал, обе рабочие станции работают на разных аппаратных средствах, но я не верю, что одна можетобъяснить разницу.Win10 имеет процессор i7, а Win7 - i3.Во всяком случае, я бы ожидал, что i3 получит больший удар (меньше кеша, меньше ресурсов ...)

Итак, хуки WH_CALLWNDPROC стали намного медленнее, чем Win7?Быстрый поиск в Google, похоже, не выявил никаких других сообщений об этой проблеме.Кто-нибудь может воспроизвести мои результаты?Если это не может быть воспроизведено, кто-нибудь знает, какие настройки / конфликтующие приложения могут быть причиной этого?(Уже пытался отключить проверку в режиме реального времени Защитником Windows, и это не повлияло на производительность.)

РЕДАКТИРОВАТЬ: Это было протестировано под Win10 1803 64 бит.Само тестовое приложение имело 32 бита.

EDIT2: то же приложение, скомпилированное в 64 бита, дает следующее время выполнения.

  • Win10: 780 мсек / 10201 мсек.
  • Win7: 6419 мсек / 9201 мсек.

EDIT3: Интересно, что при запуске приложения (32bit) от имени администратора:

  • Win10: 12693 мсек / 18028 мсек

Кроме того, (на еще одной рабочей станции) работа другого пользователя имеет значение:

  • Win10 (1809) / «обычный пользователь»: 9430/17440 мсек
  • Win10 (1809) / система: 5220/10160 мсек (запущен удаленно через PsExec)

EDIT4: при запуске от имени администратора приложение будет работать быстрее с USB-ключа, чем с жесткого диска.(Примечание. До сих пор я тестировал только систему с одним диском. На этом этапе я не исключаю, что только диск с ОС работает медленнее.)

РЕДАКТИРОВАТЬ5: Я обнаружил еще несколько вещейоб этой ситуации.Во-первых, запуск «As Admin» (win10) приводит к тому, что в приложении устанавливается хук WH_CALLWNDPROCRET.Я не нашел, откуда это (ОС, платформа Delphi, другое приложение?).Это определенно не при простом запуске приложения.

Кажется, что снижение производительности не сильно влияет на саму ловушку, а влияет на SendMessage.

Мы в контактепри поддержке Microsoft они воспроизводили аналогичные результаты (по циклу 100 КБ вместо 1 м):

  • Windows 7 - без перехвата 0,018396 секунд.
  • Windows 10 - без перехвата 0,025102 секунды.
  • Windows 7 - с крюком 0,167941 секунды.
  • Windows 10 - с крюком 1,105929 секунды.

(Расследование еще не завершено, поэтому пока нет никаких выводов)

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

1 Ответ

1 голос
/ 03 июня 2019

Итак, хуки WH_CALLWNDPROC и WH_CALLWNDPROCRET действительно значительно снижают производительность.И в несколько большей степени в Win10, чем в Win7.

Некоторая потеря производительности исходит от кода смягчения для Spectre и Meltdown.Ранние сообщения от Microsoft предполагают, что остальное, по-видимому, связано с конфликтом блокировок в оконном менеджере (win32k * .sys).

Что касается странного результата, который я получил в своем исследовании:

  • Запуск «As Admin» привел к тому, что в моем приложении была установлена ​​дополнительная ловушка, которая объясняет значительное замедление, которое я наблюдал
  • Многие из тестов, которые я проводил, были на тестовой машине, доступ к которой осуществлялся через инструмент удаленного администрирования ... что происходитустановить глобальный хук WH_CALLWNDPROC / WH_CALLWNDPROCRET, что сделало мой результат теста некорректным.Запуск локально «исправил» результаты.Мне потребовалось некоторое время, чтобы узнать об этом, так как мое приложение было 32-битным, а ловушки были 64-битными, поэтому мое приложение не было уведомлено о них (но все еще подвергалось снижению производительности).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...