Бенчмаркинг, затронутый 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 до проведения бенчмаркинга.