Нужно сообщение от ОС Windows о снятии потока с проца!!

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Eugie, Romeo, Hawk

Ответить
MobileMan
Сообщения: 3
Зарегистрирован: 13 апр 2005, 00:45

Нужно сообщение от ОС Windows о снятии потока с проца!!

Сообщение MobileMan » 14 апр 2005, 00:38

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

Tima
Сообщения: 43
Зарегистрирован: 23 сен 2004, 10:17
Откуда: Харьков
Контактная информация:

Сообщение Tima » 14 апр 2005, 11:30

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

MobileMan
Сообщения: 3
Зарегистрирован: 13 апр 2005, 00:45

Сообщение MobileMan » 17 апр 2005, 23:36

Tima писал(а):Для этой цели пользуйся функциями 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
Сообщения: 43
Зарегистрирован: 23 сен 2004, 10:17
Откуда: Харьков
Контактная информация:

Сообщение Tima » 18 апр 2005, 11:54

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

Tima
Сообщения: 43
Зарегистрирован: 23 сен 2004, 10:17
Откуда: Харьков
Контактная информация:

Сообщение Tima » 18 апр 2005, 12: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
Сообщения: 3
Зарегистрирован: 13 апр 2005, 00:45

Сообщение MobileMan » 18 апр 2005, 17:08

Большая спасиба!! Буду разбираться дальше... 8) :arrow: :!:
Достоверность информации гарантируется. Проверено и доказано!

Ответить