GetTickCount()
От: WinterMute Россия http://yarrr.ru
Дата: 09.08.05 16:32
Оценка:
Что всё-таки возвращает эта функция?
В MSDN написано что количество милисекунд, но я столкнулся с ситуацией, когда на двух разных машинах прогон одного и того-же алгоритма выполняется за примерно одинаковое количество "тиков". Так всё-таки, каких попугаев она возвращает?
Re: GetTickCount()
От: MShura  
Дата: 09.08.05 17:29
Оценка:
WM>Что всё-таки возвращает эта функция?
WM>В MSDN написано что количество милисекунд, но я столкнулся с ситуацией, когда на двух разных машинах прогон одного и того-же алгоритма выполняется за примерно одинаковое количество "тиков". Так всё-таки, каких попугаев она возвращает?

Точность GetTickCount примерно 55 миллисекунд.
Re[2]: GetTickCount()
От: WinterMute Россия http://yarrr.ru
Дата: 09.08.05 19:02
Оценка:
MS>Точность GetTickCount примерно 55 миллисекунд.

У меня дело врят-ли в погрешности измерения. Возможно, это особенность алгоритма, но мне хотелось быть уверенным, что GetTickCount() возвращает именно милисекунды, а не попугаи которые потом нужно на что-либо домножать.
Re: GetTickCount()
От: DEMON HOOD  
Дата: 09.08.05 20:24
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>Что всё-таки возвращает эта функция?

WM>В MSDN написано что количество милисекунд, но я столкнулся с ситуацией, когда на двух разных машинах прогон одного и того-же алгоритма выполняется за примерно одинаковое количество "тиков". Так всё-таки, каких попугаев она возвращает?

а как испульзуешь?

DWORD GetTickCount (void);

The returned DWORD is a count of system ticks (or milliseconds) since boot time.


Вот выделил.
Может каким то образом влияет то что компы в разное время загружены ? (малоли как ты там написал код....)

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

#include <stdio.h>
#include <windows.h>

void CPUtick(DWORD* hi,DWORD* lo)
{
DWORD h,l;
__asm
    {
        #ifdef __BCPLUSPLUS__ 
        
    db 0fh        
    db 31h      
        
        #else

        RDTSC

        #endif

           mov [h],edx     
        mov [l],eax     
    }
*hi=h;
*lo=l;
}

DWORD MHZ() 
{
DWORD h,l,lasttick=0;
DWORD time1,time2;

time1=GetTickCount();
time2=time1;
CPUtick(&h,&l);
while(time2-time1<1000)
    {
    time2=GetTickCount();
        printf("\r%c\r%c\r%c\r%c",0x7c,0x2f,0x2d,0x5c);
    }
CPUtick(&h,&lasttick);
h=(lasttick-l)/1000000;
printf("\n");
return h;
}

void TIME(DWORD mhz)
{
DWORD h,l,hour,minute;
CPUtick(&h,&l);
h=h*(4294967296/(mhz*1000000));
hour=h/3600;
minute=(h%3600)/60;
printf("Time elapsed after last boot:\n%lu hour %lu minutes \n",hour,minute);
}

void main()
{
DWORD mhz;
printf(" Please wait few seconds....");
mhz=MHZ();
printf("Your computer operates approx. at: %lu MHZ\n", mhz);
TIME(mhz);
}
silent RSDN@Home 1.1.4 stable [510] Windows XP 5.1.2600.0
Re[3]: GetTickCount()
От: Anton Batenev Россия https://github.com/abbat
Дата: 09.08.05 20:46
Оценка:
Здравствуйте, WinterMute, Вы писали:

WM>У меня дело врят-ли в погрешности измерения. Возможно, это особенность алгоритма, но мне хотелось быть уверенным, что GetTickCount() возвращает именно милисекунды, а не попугаи которые потом нужно на что-либо домножать.


Именно ms. А то, что результирующее число одинаково, так это, скорее всего, погрешность измерения. Попробуй выполнить этот алгоритм N-цать раз, так, чтобы разница интервала времени на разных машинах была существенна (30-60 сек).
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[2]: GetTickCount()
От: TarasCo  
Дата: 10.08.05 07:22
Оценка: +2
Здравствуйте, MShura, Вы писали:

MS>Точность GetTickCount примерно 55 миллисекунд.


Откуда такая цифра ???? . Почему не 40 и не 60?
Точность GetTickCount относительно реального времени определяется величиной кванта времени задачи и количеством активных задач и процессоров в системе. В настольных системах это обыно 10 или 15мс — точнее измерить время не удастся. На серверах квант может быть длинее. Может, отсюда такая цифра (55) ?

http://rsdn.ru/Forum/Message.aspx?mid=840985&amp;only=1
Автор: Valerio
Дата: 07.10.04
Да пребудет с тобою сила
Re[3]: GetTickCount()
От: MShura  
Дата: 10.08.05 07:35
Оценка:
Здравствуйте, TarasCo, Вы писали:

TC>Здравствуйте, MShura, Вы писали:


MS>>Точность GetTickCount примерно 55 миллисекунд.


TC>Откуда такая цифра ???? . Почему не 40 и не 60?


Как говорит MSDN точность можно узнать с помощью GetSystemTimeAdjustment.
55 миллисекунд это 18Гц. Был (есть) такой настоящий таймер в PC.

А если честно, то число 55 в первую очередь это было взято из комментариев:

DWORD
GetTickCount(
    VOID
    )

/*++

Routine Description:

    Win32 systems implement a free-running millisecond counter.  The
    value of this counter can be read using GetTickCount.

Arguments:

    None.

Return Value:

    This function returns the number of milliseconds that have elapsed
    since the system was started. If the system has been running for
    a long time, it is possible that the count will repeat. The value of
    the counter is accurate within 55 milliseconds.

--*/

{
    return (DWORD)NtGetTickCount();
}




TC>Точность GetTickCount относительно реального времени определяется величиной кванта времени задачи и количеством активных задач и процессоров в системе. В настольных системах это обыно 10 или 15мс — точнее измерить время не удастся. На серверах квант может быть длинее. Может, отсюда такая цифра (55) ?


TC>http://rsdn.ru/Forum/Message.aspx?mid=840985&amp;only=1
Автор: Valerio
Дата: 07.10.04
Re[3]: GetTickCount()
От: rus blood Россия  
Дата: 10.08.05 07:40
Оценка:
Здравствуйте, TarasCo, Вы писали:

TC>Здравствуйте, MShura, Вы писали:


MS>>Точность GetTickCount примерно 55 миллисекунд.


TC>Откуда такая цифра ???? . Почему не 40 и не 60?


Очевидно, это 1000ms / 18.2
Имею скафандр — готов путешествовать!
Re[4]: GetTickCount()
От: TarasCo  
Дата: 10.08.05 08:29
Оценка: 1 (1)
Здравствуйте, MShura, Вы писали:

MS>Здравствуйте, TarasCo, Вы писали:


TC>>Здравствуйте, MShura, Вы писали:


MS>>>Точность GetTickCount примерно 55 миллисекунд.


TC>>Откуда такая цифра ???? . Почему не 40 и не 60?


MS>Как говорит MSDN точность можно узнать с помощью GetSystemTimeAdjustment.

MS>55 миллисекунд это 18Гц. Был (есть) такой настоящий таймер в PC.

MS>А если честно, то число 55 в первую очередь это было взято из комментариев:


MS>
MS>DWORD
MS>GetTickCount(
MS>    VOID
MS>    )

MS>/*++

MS>Routine Description:

MS>    Win32 systems implement a free-running millisecond counter.  The
MS>    value of this counter can be read using GetTickCount.

MS>Arguments:

MS>    None.

MS>Return Value:

MS>    This function returns the number of milliseconds that have elapsed
MS>    since the system was started. If the system has been running for
MS>    a long time, it is possible that the count will repeat. The value of
MS>    the counter is accurate within 55 milliseconds.

MS>--*/

MS>{
MS>    return (DWORD)NtGetTickCount();
MS>}
MS>


Решил проверить, написал следующее:

    DWORD        a = GetTickCount();
    DWORD        t1 = a;

    do {
    
    DWORD    t2 = GetTickCount();

    if ( t2 > t1 )
    {
        t1 = t2;
        printf( "%d\n", t1 - a );
    }

    } while ( 1 );


У меня программа выводит числа с интервалом 15-16, что как раз соответсвует частоте таймера и частоте переключения задач
Да пребудет с тобою сила
Re[5]: GetTickCount()
От: MShura  
Дата: 10.08.05 08:54
Оценка:
MS>>>>Точность GetTickCount примерно 55 миллисекунд.

TC>>>Откуда такая цифра ???? . Почему не 40 и не 60?


MS>>Как говорит MSDN точность можно узнать с помощью GetSystemTimeAdjustment.

MS>>55 миллисекунд это 18Гц. Был (есть) такой настоящий таймер в PC.

MS>>А если честно, то число 55 в первую очередь это было взято из комментариев:


TC>Решил проверить, написал следующее:


TC>
TC>    DWORD        a = GetTickCount();
TC>    DWORD        t1 = a;

TC>    do {
    
TC>    DWORD    t2 = GetTickCount();

TC>    if ( t2 > t1 )
TC>    {
TC>        t1 = t2;
TC>        printf( "%d\n", t1 - a );
TC>    }

TC>    } while ( 1 );
TC>


TC>У меня программа выводит числа с интервалом 15-16, что как раз соответсвует частоте таймера и частоте переключения задач


Пожалуй комментарии к GetTickCount() устарели....
Последняя модификация файла содержащего реализацию этой функции 2000 год.
А в заголове сказано, что он был создан в 1990 году.
Так что не мудрено, что алгоритм функции был изменен, а комментарии нет.


Если обратиться к NtGetTickCount(), то имеем:

ULONG
NtGetTickCount (
   VOID
   )

/*++

Routine Description:

    This function computes the number of milliseconds since the system
    was booted. The computation is performed by multiplying the clock
    interrupt count by a scaled fixed binary multiplier and then right
    shifting the 64-bit result to extract the 32-bit millisecond count.

    The multiplier fraction is scaled by 24 bits. Thus for a 100 Hz clock
    rate, there are 10 ticks per millisecond, and the multiplier is
    0x0a000000 (10 << 24). For a 128 Hz clock rate, there are 7.8125, or
    7 13/16 ticks per millisecond, and so the multiplier is 0x07d00000.

    This effectively replaces a (slow) divide instruction with a (fast)
    multiply instruction. The multiplier value is only calculated once
    based on the TimeIncrement value (clock tick interval in 100ns units).

    N.B. The tick count value wraps every 2^32 milliseconds (49.71 days).

Arguments:

    None.

Return Value:

    The number of milliseconds since the system was booted is returned
    as the function value.

--*/

{
    ULONGLONG Product;

    //
    // compute unsigned 64-bit product
    //

    Product = (ULONGLONG)KeTickCount * ExpTickCountMultiplier;

    //
    // shift off 24-bit fraction part and 
    // return the 32-bit canonical ULONG integer part.
    //
            
    return ((ULONG)(Product >> 24));
}
Re[6]: GetTickCount()
От: Left2 Украина  
Дата: 10.08.05 10:27
Оценка:
Дело не в этом
Используется вывод на консоль (printf), а он наверняка делает скроллинг — в итоге ты меряешь скорость вывода на консоль. Попробуй не вызывать printf, а к примеру складывать значения в массив и потом его распечатать — получишь (насколько я понимаю) равномерно увеличивающиеся значения.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[7]: GetTickCount()
От: TarasCo  
Дата: 10.08.05 10:39
Оценка:
Здравствуйте, Left2, Вы писали:

L>Дело не в этом

L>Используется вывод на консоль (printf), а он наверняка делает скроллинг — в итоге ты меряешь скорость вывода на консоль. Попробуй не вызывать printf, а к примеру складывать значения в массив и потом его распечатать — получишь (насколько я понимаю) равномерно увеличивающиеся значения.

Во первых, я боролся с цифрой 55 и это удалось )))))))
А на счет консоли — все очень сложно. Могу скахзать одно, скроллинг и другая прорисовка консольного окна происходит не в потоке, выполнившем printf. Кроме того, Вы не внимательно смотрели код — printf вызывается, если только изменилось значение счетчика. И у меня большие сомнения, что прорисока консоли по времени может быть сравнима с величиной 15мс.
Да пребудет с тобою сила
Re[4]: GetTickCount()
От: WinterMute Россия http://yarrr.ru
Дата: 10.08.05 10:42
Оценка:
Здравствуйте, Anton Batenev, Вы писали:

AB>Именно ms. А то, что результирующее число одинаково, так это, скорее всего, погрешность измерения. Попробуй выполнить этот алгоритм N-цать раз, так, чтобы разница интервала времени на разных машинах была существенна (30-60 сек).


Я так и делаю. Возможно проблемы никакой и нет, но меня смутило вот что: первый компьютер -- "P3 Celeron 800, PC133", второй "P2 Celeron 1700, PC266", тестируемая процедура активно обращается к памяти (выполняется свёртка), но время выполнения на обоих машинах примерно равно (разница в пределах 10%).
Re[5]: GetTickCount()
От: Anton Batenev Россия https://github.com/abbat
Дата: 11.08.05 02:37
Оценка:
Здравствуйте, WinterMute, Вы писали:

AB>>Именно ms. А то, что результирующее число одинаково, так это, скорее всего, погрешность измерения. Попробуй выполнить этот алгоритм N-цать раз, так, чтобы разница интервала времени на разных машинах была существенна (30-60 сек).

WM>Я так и делаю. Возможно проблемы никакой и нет, но меня смутило вот что: первый компьютер -- "P3 Celeron 800, PC133", второй "P2 Celeron 1700, PC266", тестируемая процедура активно обращается к памяти (выполняется свёртка), но время выполнения на обоих машинах примерно равно (разница в пределах 10%).

Стоп! Я писал о том, чтобы сделать такое количество иттераций, чтобы время выполнения на машине А превышало время выполнения на машине Б на 30-60 сек (а при достаточно большом количестве иттераций такое достижимо). После чего, замерить время выполнения на А и на Б, провести опыт как минимум 3 раза (чем больше тем лучше)... Отбрось выбросы, вычисли среднее, СКО, дисперсию, доверительные интервалы и т.д. (гы-гы) и получишь, собственно, время выполнения (в условных единицах) и погрешность GetTickCount() в этих же единицах. Согласно документации, эта условная единица — ms. Поскольку нет эталона дабы сравнить единицы с ms — придется поверить документации на слово (хотя, например, можно сравнить время выполнения со значением секундомера, но тогда точность GetTickCount у тебя упадет еще больше, нежели заявлено в документации).

А вообще, ради интереса, можно посмотреть здесь — вроде как библиотека претендует на замеры времени выполнения с большой точностью, я ее попробовал, посмотрел — вроде что-то считает не сильно отличающееся от GetTickCount, а если не видно разницы — зачем заморачиваться?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.