Бенчмаркинг, затронутый VCL

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

от Borland С++ builder 5.0 до BDS2006 Turbo С++ и обнаружил странную вещь.

  • exe из BCB5 работает нормально и стабильно
  • exe из BDS2006 измеряет OK только до того, как начнется основная форма (внутри ее конструктора), и если эталонный тест снова запущен после того, как основная форма Activated или даже после любого VCLсильная > смена компонента (например, Caption основной формы), то скорость тестового потока сильно зависит.

VCL memory benchmark

После некоторых исследований я узнал, что:

  • Не выполняется, если тест внутри нити или нет.
  • Приоритет процесса/потока, сродство также не влияют на это.
  • Скрыть любое окно (Visibility,Enabled) не влияет на это.
  • вызов тестовой формы OnIdleEvent не влияет на это
  • не выполняется, если время измерено с помощью RDTSC или PerformanceCounter

Мой вывод состоит в том, что библиотека VCL запускает некоторый код/​​поток в фоновом режиме, поэтому мои вопросы:

  • Есть ли способ временно приостановить VCL-код/​​материал?

    идеально что-то вроде Application->Pause(); и Application->Resume(); или просто Forms.

  • что еще может вызвать такое поведение и как его избежать?

PS.

В тестовом приложении нет VCL, кроме основной формы. Benchmark - это всего лишь несколько передач памяти rep stosd с разными размерами блоков (без смешных вещей). Источник находится в этом связанном Q/A. Я знаю, что BDS2006 устарел, но сейчас я не ищу обновления, поэтому прошу прокомментировать любые комментарии о том, что они вообще не помогают.

Протестировано в Windows7 pro x64, 32bit Приложении

Ответ 1

Я узнал, что wndproc в BDS2006:: VCL invalidates CACHE.

  • Я попытался переопределить wndproc на winapi

    для Application->Handle легко, но это не останавливает обработку сообщений для Form. Когда я пробовал Form1->Handle как окно, тогда возникает error 1400 (недействительный дескриптор окна)

  • Я попытался переопределить wndproc с помощью VCL

    для приложения TApplication events и для Form путем переопределения виртуального члена wndproc. Обработка сообщений останавливается, но их вызывающие последовательности остаются, и проблема также не решена.

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

В DOS я бы сделал это с помощью одной инструкции, но в windows это более сложно. Ну предыдущая версия теста памяти использовала только заполнение памяти, чего явно недостаточно для BDS2006 exe. Я думаю, что в этой проблеме не используется команда CACHE, а не кеш данных, поэтому я немного меняю ее, и она, в конце концов, сработала.

Промывка CPU CACHE:

for (DWORD i=0;i<(128<<20);i+=7)
    {
    dat[i]+=i;
    dat[i]*=i;
    dat[i]&=i;
    }

Где находится 128MB выделенный фрагмент памяти (или больше) и должен выполняться после всех приоритетов процесса и потока, аффинности или всех вызовов winapi до проведения бенчмаркинга.