PDA

Просмотр полной версии : Нужно сообщение от ОС Windows о снятии потока с проца!!



MobileMan
14.04.2005, 01:38
Постановка вопроса:
"Разрабатывается программа под ОС Windows 2000. Одним из её элементов является замер времени выполнения определённых фрагментов кода. Есть функция для снятия показаний системного таймера. Эти функция вызывается в начале процесса замера и по его окончании. Вот тут и возникает проблема. Замеренное время больше реального времени выполнения этого фрагмента кода. И дело тут вот в чём: как известно, Windows - многозадачная ОС, поэтому в какие-то моменты процесс (для которого производится замер) снимается с процессора, и на процессоре выполняется другой процесс (например, какой-нибудь системный), потом наш процесс возвращается на процессор. В результирующее время попадают те интервалы времени, в которые на процессоре находятся посторонние процессы. Выход представляется таким: снимать показания системного таймера перед снятием с процессора и после постановки на процессор нашего процесса, и исключать продолжительность этих промежутков из общего времени. Вот только как отловить моменты, в которые происходит снятие с процессора и постановка на процессор нашего процесса. Может Windows посылает какое-нибудь сообщение процессу, типа: "Вот ты сейчас будешь снят" и "Сейчас ты вернёшься на процессор". Но какие это сообщения мне неизвестно. Есть версия, что эта информация относится к недокументированным возможностям Windows."
Буду очень благодарен всем тем, кто сможет предложить разумные идеи для решения поставленной проблемы. Особо отличившихся угощу пивком!! :D
Всем заранее спасибо!!

Tima
14.04.2005, 12:30
И дело тут вот в чём: как известно, Windows - многозадачная ОС, поэтому в какие-то моменты процесс (для которого производится замер) снимается с процессора, и на процессоре выполняется другой процесс (например, какой-нибудь системный), потом наш процесс возвращается на процессор. В результирующее время попадают те интервалы времени, в которые на процессоре находятся посторонние процессы
Для этой цели пользуйся функциями GetThreadTimes и GetProcessTimes. Должно быть все ОК.

MobileMan
18.04.2005, 00:36
Для этой цели пользуйся функциями GetThreadTimes и GetProcessTimes. Должно быть все ОК.
Я нашёл синтаксис функции GetProcessTimes():

BOOL GetProcessTimes(
HANDLE hProcess, // дескриптор процесса
LPFILETIME lpCreationTime, // время создания процесса
LPFILETIME lpExitTime, // время выхода из работы процесса
LPFILETIME lpKernelTime, // время, работы процесса в режиме ядра
LPFILETIME lpUserTime // время, работы процесса в режиме пользователя
);

Правильно ли я понимаю, что для замера времени выполнения некоторого участка кода нужно вызвать эту функцию до этого участка (сохраняем при этом lpKernelTime и lpUserTime) и после этого участка (снова сохраняем lpKernelTime и lpUserTime), далее вычитаем из последнего lpKernelTime первый lpKernelTime (возможно, предварительно преобразовав время в другой формат, более удобный для вычитания?), при этом получаем время работы процесса в режиме ядра. Также из последнего lpUserTime вычитаем первый lpUserTime и получаем время работы процесса в пользовательском режиме.
Теперь вопрос: общее время работы процесса вычисляется как сумма времени в режиме ядра и в пользовательском режиме? Или общее время выполнения считается каким-то более хитрым способом?
И ещё: чем работа процесса в режиме ядра отличается от его работы в пользовательском режиме? :?: :?: :?: 8)

Tima
18.04.2005, 12:54
для замера времени выполнения некоторого участка кода нужно вызвать эту функцию до этого участка (сохраняем при этом lpKernelTime и lpUserTime) и после этого участка (снова сохраняем lpKernelTime и lpUserTime), далее вычитаем из последнего lpKernelTime первый lpKernelTime (возможно, предварительно преобразовав время в другой формат, более удобный для вычитания?),
Да, вобщем. Но тут один нюанс. Нужно вычитать первое значение из второго в виде int64. Для этого пользуйся макросами FileTimeToQuadWord. Потом суммируешь оба значения для User и Kernel режимов (тоже в виде int64).


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

Tima
18.04.2005, 13:31
Поправлюсь: FileTimeToQuadWord конечно не макрос, а пользовательская функция.
_int64 FileTimeToQuadWord(PFILETIME ptt)
{
return(Int64ShllMod32(pft->dwHighDateTime, 32) | pft->dwLowDateTime);
}
Примеры из Рихтера.
Это следует делать потому, что в MSDN написано:
It is not recommended that you add and subtract values from the FILETIME structure to obtain relative times.

MobileMan
18.04.2005, 18:08
Большая спасиба!! Буду разбираться дальше... 8) :arrow: :!: