то есть я должен получать 1000 мсек паузы
Адекватную цифру (примерно или ровно 1000) я получаю только при использовании KeQueryPerformanceCounter
а при использовании первых двух способов я получаю или например 1953 или например 15689, какая конкретная цифра, это зависит от компьютера
то же самое контролирую на 3-м кольце:
LARGE_INTEGER Frequency, StartPerformCount, StopPerformCount;
int bHighRes = QueryPerformanceFrequency (&Frequency);
QueryPerformanceCounter (&StartPerformCount);
// здесь вызов DeviceIoControl который выполняет вышеуказанный Sleep цикл
QueryPerformanceCounter (&StopPerformCount);
double msTime = (double)(StopPerformCount.QuadPart - StartPerformCount.QuadPart) / (double)Frequency.QuadPart * 1.E3;
ну и ручные часы и устный счет секунд ( ) говорит о том, что первые два способа выполняются дольше, чем должны бы.
Скажите плиз где я неправ или у вас такая же фигня?
заранее всем спасибо
Re: аналог Sleep в ядре
От:
Аноним
Дата:
01.02.12 12:52
Оценка:
D>ну и ручные часы и устный счет секунд ( ) говорит о том, что первые два способа выполняются дольше, чем должны бы. D>Скажите плиз где я неправ или у вас такая же фигня? D>заранее всем спасибо
Это фигня называется квант процессорного времени. Любая функция, выполняющая ожидание, отдает квант от вызвавшего потока другому. Соответственно, ваш поток, даже если его просили спать 500мкс, проспит до окончания отданного кванта ( а то и дольше если будут более приоритетные задачи ) когда случится перепланировка. Единственный вариант проснутся раньше — это досрочная перепланировка. Она может случиться например после окончания высокприоритетной операции ввода/вывода.
Бороться с этим грозным явлением можно только укорачивая квант. Он должен не превосходить точность, с которой вы собираетсь отмерять интервалы.
Здравствуйте, Аноним, Вы писали:
D>>ну и ручные часы и устный счет секунд ( ) говорит о том, что первые два способа выполняются дольше, чем должны бы. D>>Скажите плиз где я неправ или у вас такая же фигня? D>>заранее всем спасибо
А>Это фигня называется квант процессорного времени. Любая функция, выполняющая ожидание, отдает квант от вызвавшего потока другому. Соответственно, ваш поток, даже если его просили спать 500мкс, проспит до окончания отданного кванта ( а то и дольше если будут более приоритетные задачи ) когда случится перепланировка. Единственный вариант проснутся раньше — это досрочная перепланировка. Она может случиться например после окончания высокприоритетной операции ввода/вывода.
А>Бороться с этим грозным явлением можно только укорачивая квант. Он должен не превосходить точность, с которой вы собираетсь отмерять интервалы.
Спасибо! Поразмышлял и поэкспериментировал, в том числе над самой функцией Sleep(). Получилось, что адекватное время выдерживается слипом тогда, когда он близок к какой-то величине, наверное к этому кванту, который как я понимаю обычно составляет 10-20 или больше миллисекунд.
У меня получилось, что Sleep() на 3-м кольце ведёт себя точно так же, как интервальный таймер и KeDelayExecutionThread на нулевом кольце. И меньше чем на 10 или больше миллисекунд (на разных компах по-разному) засыпать нет смысла.
Если выводы неправильны, поправьте, плиз.
Re[3]: аналог Sleep в ядре
От:
Аноним
Дата:
02.02.12 13:04
Оценка:
D>Спасибо! Поразмышлял и поэкспериментировал, в том числе над самой функцией Sleep(). Получилось, что адекватное время выдерживается слипом тогда, когда он близок к какой-то величине, наверное к этому кванту, который как я понимаю обычно составляет 10-20 или больше миллисекунд. D>У меня получилось, что Sleep() на 3-м кольце ведёт себя точно так же, как интервальный таймер и KeDelayExecutionThread на нулевом кольце. И меньше чем на 10 или больше миллисекунд (на разных компах по-разному) засыпать нет смысла. D>Если выводы неправильны, поправьте, плиз.
В общем да. Остается добавить, что квант можно уменьшить, в том числе и из юзер мода. Многие проги уменьшают его до 1ms и даже меньше.
D>>Спасибо! Поразмышлял и поэкспериментировал, в том числе над самой функцией Sleep(). Получилось, что адекватное время выдерживается слипом тогда, когда он близок к какой-то величине, наверное к этому кванту, который как я понимаю обычно составляет 10-20 или больше миллисекунд. D>>У меня получилось, что Sleep() на 3-м кольце ведёт себя точно так же, как интервальный таймер и KeDelayExecutionThread на нулевом кольце. И меньше чем на 10 или больше миллисекунд (на разных компах по-разному) засыпать нет смысла. D>>Если выводы неправильны, поправьте, плиз.
А>В общем да. Остается добавить, что квант можно уменьшить, в том числе и из юзер мода. Многие проги уменьшают его до 1ms и даже меньше.
Это распространенное, но все же заблуждение. Изменение частоты системного таймера практически не оказывает влияния на длительность кванта. Почему — описано например вот здесь: http://www.rsdn.ru/forum/winapi/4159851.1.aspx
По теме, собственно, Вам ответили, а у меня другой вопрос — такое нынче считается хорошим стилем программирования? В смысле — динамическое выделение малого количества памяти, используемой локально в блоке.
ЕМ>По теме, собственно, Вам ответили, а у меня другой вопрос — такое нынче считается хорошим стилем программирования? В смысле — динамическое выделение малого количества памяти, используемой локально в блоке.
Эта память должна быть в device extension или в nonpaged pool. Как должен был поступить стильный программер?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, <Аноним>, Вы писали:
А>>Многие проги уменьшают его до 1ms и даже меньше.
ЕМ>Чтоб меньше — нужно HAL переделывать. Стандартный даст минимум 976 мкс.
Так можно выдерживать паузу гарантированно (ну хотя бы примерно) в 1 мсек?
Здравствуйте, x64, Вы писали:
D>>Как должен был поступить стильный программер?
x64>Разместить объект на стеке. x64>По поводу выгрузки стека здесь:
x64>
x64>Stack swapping never occurs for wait states that are initiated by kernel-mode components, regardless of whether stack swapping is enabled.
стек в режиме ядра можно считать nonpaged?
не знал, спасибо
зы: хотя по-другому было бы не логично
Нет, стек в режиме ядра paged, если явно не указано иное, но на время ядерного ожидания (т.е. параметр WaitMode = KernelMode) стек становится non-paged.
Здравствуйте, x64, Вы писали:
D>>стек в режиме ядра можно считать nonpaged?
x64>Нет, стек в режиме ядра paged, если явно не указано иное, но на время ядерного ожидания (т.е. параметр WaitMode = KernelMode) стек становится non-paged.
Все неверно. Стек потока в ядре невыгружаемый, за исключением момента, когда поток висит в ожидании, к примеру KeWaitForSingleObject с аргументом UserMode, в этом случае системный поток KeSwapProcessOrStack по прошествии некоторого времени превратит странички стека из невыгружаемых в выгружаемые.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, dorador, Вы писали:
D>>Эта память должна быть в device extension или в nonpaged pool.
ЕМ>А в device extension какая-то особенная память?
да, device extension размещается в nonpaged pool , но я просто цитировал описание KeInitializeTimer
Storage for a timer object must be resident: in the device extension of a driver-created device object, in the controller extension of a driver-created controller object, or in nonpaged pool allocated by the caller.