Замерение времени исполнения системного вызова

Тема в разделе "WASM.WIN32", создана пользователем Mika0x65, 4 янв 2011.

  1. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Мое почтение всем.

    Для вычисления прожорливых системных вызовов необходимо замерить их время исполнения. Вызовы перехватываются в ntdll.dll (все Nt* ф-ии с проверкой сигнатуры). Счетчики, получаемые в NtQuerySystemInformation обновляются слишком редко (примерно раз в 15 миллисекунд по моим подсчетам). Есть мысль использовать QueryPerfomanceCounter, но, во-первых, информация о точности вызова достаточно противоречивая, во-вторых, непонятно, учитывает ли QueryPerfomanceCounter переключения контекста и спячку потока.

    Немного о задаче: На 64битной платформе (Server 2003, 8 cores, 4GB) целевая программа работает с MS SQL Server 2005/2008 посредством ReadProcessMemory. Один и тот же код потребляет 11 секунд времени ядра на при работе с 2005 и 27 секунд при работе с 2008. Пользовательское время 4 секунды для 2005ого и 30 секунд для 2008ого. Общее время работы программы десять минут. Задача понять, откуда берется увеличение времени работы процесса в режиме ядра. Кстати, в режиме поользователя тоже желательно :).

    Пока писал сообщение, подсказали, что QueryPerfomanceCounter не учитывает переключение потоков. Жаль.

    В общем, нуждаюсь в совете, что делать. Valgrind (как мне сказали), слишком затармаживыет программу. Сам не пробовал.

    Заранее благодарен.
     
  2. slesh

    slesh New Member

    Публикаций:
    0
    Регистрация:
    6 фев 2009
    Сообщения:
    214
    GetThreadTimes делай. Затем пару тысяч раз вызывай нужную апишку в цикле, затем опять вызывай GetThreadTimes
    Для тебя важным будет значение KernelTime - т.е. время потраченное на обработку команды в ядре. Потом вычислишь среднее время выполнения для конкретной апишки. Если быть более точным, то тоже еще и бери UserTime чтобы знать сколько времени выполняется апишка в юзермоде перед переходом в ядро, т.е. тот код который в kernel32.dll/ntdll.dll и тому подобных либах.