Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Высокоточные часы


Автор: CPlusPlusFAN 26.2.2008, 21:16
Здравствуйте. timeGetTime() возвращает время в милисекундах. Можно ли увеличить точность хотя бы до 0.1 ms, т.е. узнать время в десятых долях милисекунды?

Автор: PPS05 26.2.2008, 22:16
Как вариант: использовать QueryPerformanceCounter (вернет значение высокоточного счетчика) и QueryPerformanceFrequency (частота). Если поделить разность значений счетчиков на частоту, получишь значение временного интервала в микросекундах. Параметры писать не стал - там тривиально LARGE_INTEGER *.

Автор: jonie 28.2.2008, 02:31
буду не оригинальным - внешняя система+ос реального времени)

Автор: MuForum 19.11.2008, 17:30
Цитата(PPS05 @ 26.2.2008,  22:16)
Как вариант: использовать QueryPerformanceCounter (вернет значение высокоточного счетчика) и QueryPerformanceFrequency (частота). Если поделить разность значений счетчиков на частоту, получишь значение временного интервала в микросекундах. Параметры писать не стал - там тривиально LARGE_INTEGER *.

Код

float GetQPTIME(int _Sleep)
{
        float dif = 0;
        LARGE_INTEGER a, b, c;
        //start time
        QueryPerformanceFrequency(&c);
        QueryPerformanceCounter(&a);
        //Do something
        Sleep(_Sleep);
        //end time
        QueryPerformanceCounter(&b);
        dif = ((float)(b.QuadPart - a.QuadPart)/(float)(c.QuadPart));
        // ----
        return dif;
}

- Сделал как ты написал, но к сожалению результат не совсем устраивает...
- Всё равно не совсем чутко работает.
- Может можно ещё как-то увеличить точность в замерах?


P.S. -> Сейчас капаю в сторону http://ru.wikipedia.org/wiki/Rdtsc
- Отпишусь о результате...


# Добавлено: Выше показанный способ оказался эффективнее других WinApi функций:
Цитата

# GetTickCount(): http://msdn.microsoft.com/en-us/library/ms724408(VS.85).aspx; http://ru.wikipedia.org/wiki/GetTickCount;
// ----
# TimeGetTime(): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_timegettime.asp;
# TimeBeginPeriod(): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_timebeginperiod.asp;
# TimeEndPeriod(): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_timeendperiod.asp;
// ----
# Sleep(): http://msdn.microsoft.com/en-us/library/ms686298(VS.85).aspx;
// ----
# QueryPerformanceCounter(): http://msdn.microsoft.com/en-us/library/ms644904.aspx;
# QueryPerformanceFrequency(): http://msdn.microsoft.com/en-us/library/ms644905(VS.85).aspx;



Автор: Alexeis 19.11.2008, 17:49
  Можно на время замера отключить все прерывания, тогда по идее никто не сможет помешать, но винда перестанет быть многозадачной smile .

Автор: GremlinProg 19.11.2008, 20:46
Цитата(PPS05 @  27.2.2008,  00:16 Найти цитируемый пост)
Если поделить разность значений счетчиков на частоту, получишь значение временного интервала в микросекундах

Цитата(QueryPerformanceFrequency)

The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists. The frequency cannot change while the system is running.

Syntax
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);

Parameters

lpFrequency
[out] Pointer to a variable that receives the current performance-counter frequency, in counts per second. If the installed hardware does not support a high-resolution performance counter, this parameter can be zero. 
Return Value

If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. For example, if the installed hardware does not support a high-resolution performance counter, the function fails. 

конечно, таким способом можно получить время в секундах, хотя, выбрав после этого нужный делитель, можно и микросекунды извлечь.

частота дискретизации счетчика зависит от мощей и уровня загруженности проца, вот он и называется performance-counter

основной минус в том, что сам счетчик нестабилен, частота плавает, отсюда небольшие (а порой и большие) погрешности

нужно еще учесть, что на разных процах результат будет скорее разный, чем одинаковый, поэтому во время замеров рекомендуется закреплять процесс или поток на каком-нибудь одном (если, конечно, процов несколько).

Автор: Kallikanzarid 21.11.2008, 21:39
MuForum, в документации к DirectX SDK написано, что Rdtsc будет давать некорректные результаты, если изменится частота процессора (например, из-за Cool'n'Quite) или переноса потока на другое ядро. С первым бороться вряд ли удастся, но во избежание второго поток, в котором производится замер, лучше привязать к конкретному ядру с помощью SetProcessorAffinityMask.

Но что-то я повторяю за другими  smile 

Автор: MuForum 25.11.2008, 18:06
Цитата(GremlinProg @ 19.11.2008,  20:46)
Цитата(PPS05 @  27.2.2008,  00:16 Найти цитируемый пост)
Если поделить разность значений счетчиков на частоту, получишь значение временного интервала в микросекундах

Цитата(QueryPerformanceFrequency)

The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists. The frequency cannot change while the system is running.

Syntax
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);

Parameters

lpFrequency
[out] Pointer to a variable that receives the current performance-counter frequency, in counts per second. If the installed hardware does not support a high-resolution performance counter, this parameter can be zero. 
Return Value

If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. For example, if the installed hardware does not support a high-resolution performance counter, the function fails. 

конечно, таким способом можно получить время в секундах, хотя, выбрав после этого нужный делитель, можно и микросекунды извлечь.

частота дискретизации счетчика зависит от мощей и уровня загруженности проца, вот он и называется performance-counter

основной минус в том, что сам счетчик нестабилен, частота плавает, отсюда небольшие (а порой и большие) погрешности

нужно еще учесть, что на разных процах результат будет скорее разный, чем одинаковый, поэтому во время замеров рекомендуется закреплять процесс или поток на каком-нибудь одном (если, конечно, процов несколько).

Ты оказался прав.
- Даже не трогая ядра, на разных компьютерах разные результаты. (Конфигурация примерно одинаковая)
- Так что данный вариант не годится =(

Автор: jonie 27.11.2008, 01:14
вы все еще не уверовали в мой вариант?) (http://forum.vingrad.ru/index.php?showtopic=198098&view=findpost&p=1427074)

значит вас плохо учили в курсе "Операционные системы"....

Автор: allsolovey 23.2.2009, 17:34
Почему в Borland C 3.1 не работает GetTickCount().Компилируется а вот при запуске ошибка Undefined symbol GETTICKCOUNT in module ..cpp.Windows.h подключен.

Автор: GoldFinch 23.2.2009, 17:46
говоря о времени в винде надо помнить что это не ОС реального времени. в пределах последовательно квантов времени одного потока время реальное, но по истечению этих квантов поток спит неопределенное время пока снова не получит свои кванты времени

Добавлено через 1 минуту и 9 секунд
гхм... некропост однако


allsolovey, выкинь Borland C 3.1, и вообще - не умеешь настроить свой компилятор  -не берись %)

Автор: allsolovey 23.2.2009, 18:00
Я измеряю время работы функции.В билдере время выводит как надо.Что мне в Borland C 3.1 надо настроить?   

Автор: Alexeis 23.2.2009, 19:29
Цитата(allsolovey @  23.2.2009,  17:00 Найти цитируемый пост)
Я измеряю время работы функции.В билдере время выводит как надо.Что мне в Borland C 3.1 надо настроить?    

 Borland C 3.1 вроде досовский, а функция GetTickCount виндовая.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)