Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.programming > #6667 > unrolled thread

Time measuring on Windows

Started byBartC <bc@freeuk.com>
First post2016-05-29 10:53 +0100
Last post2016-05-29 19:04 +0200
Articles 4 — 2 participants

Back to article view | Back to comp.programming


Contents

  Time measuring on Windows BartC <bc@freeuk.com> - 2016-05-29 10:53 +0100
    Re: Time measuring on Windows "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2016-05-29 17:16 +0200
      Re: Time measuring on Windows BartC <bc@freeuk.com> - 2016-05-29 17:32 +0100
        Re: Time measuring on Windows "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2016-05-29 19:04 +0200

#6667 — Time measuring on Windows

FromBartC <bc@freeuk.com>
Date2016-05-29 10:53 +0100
SubjectTime measuring on Windows
Message-ID<niee0v$ded$1@dont-email.me>
I need to measure how long short processes take to execute.

All the docs point to using QueryPerformanceCounter() (as opposed to 
using, for example, the RDTSC machine instruction).

But I'm getting crazy results.

If I call QPC(), then count to ten million (a task that should take 8ms 
based on how long it took to count to a billion), and call it again, the 
difference between the two readings should give an indication of how 
long it took.

But I've seen results from 180,000 to over 600,000! (Even RDTSC gives me 
20M to 42M, but that's across two cores; I thought QPC was supposed to 
fix that). I understand values need to be scaled to get actual times, 
but the problem is they are inconsistent.

Is there a more reliable way of measuring execution times in the 
millisecond range?

(This is for a process within a program; I don't want to use an external 
utility to measure the complete runtime of an executable as that will 
include all sorts of overheads.)

-- 
Bartc

[toc] | [next] | [standalone]


#6668

From"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Date2016-05-29 17:16 +0200
Message-ID<nif14l$19hb$1@gioia.aioe.org>
In reply to#6667
On 2016-05-29 11:53, BartC wrote:
> I need to measure how long short processes take to execute.
>
> All the docs point to using QueryPerformanceCounter() (as opposed to
> using, for example, the RDTSC machine instruction).
>
> But I'm getting crazy results.
>
> If I call QPC(), then count to ten million (a task that should take 8ms
> based on how long it took to count to a billion), and call it again, the
> difference between the two readings should give an indication of how
> long it took.
>
> But I've seen results from 180,000 to over 600,000! (Even RDTSC gives me
> 20M to 42M, but that's across two cores; I thought QPC was supposed to
> fix that). I understand values need to be scaled to get actual times,
> but the problem is they are inconsistent.

They are consistent, we are using performance counter for fine time 
measurements. The time in seconds is obtained with 
QueryPerformanceFrequency. Ticks do not make sense. 8ms is too short for 
statistically correct measurements, e.g. when your thread loses 
processor it will not return until next 10ms on a busy machine.

> Is there a more reliable way of measuring execution times in the
> millisecond range?

The method is very reliable though time measurement are tricky, 
especially in presence of time sharing. Under Windows, depending on 
settings, switching threads that do not enter non-busy waiting takes 
10ms to 1ms (which is the minimum), controlled by timer resolution. In 
order to ensure 1ms timer resolution call timeBeginPeriod (1) and see if 
the spread decreases. You can also set the thread priority to 
above-normal or even real-time.

> (This is for a process within a program; I don't want to use an external
> utility to measure the complete runtime of an executable as that will
> include all sorts of overheads.)

Well, you cannot measure thread CPU time under Windows, if that is what 
you mean. Performance counter is for very accurate and fine real-time 
measurements.

Thread's CPU and kernel times can be queried but the result has a 
systematic error in it. Theoretically you can have 100% load with 0% CPU 
time indicated.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

[toc] | [prev] | [next] | [standalone]


#6669

FromBartC <bc@freeuk.com>
Date2016-05-29 17:32 +0100
Message-ID<nif5cq$r6u$1@dont-email.me>
In reply to#6668
On 29/05/2016 16:16, Dmitry A. Kazakov wrote:
> On 2016-05-29 11:53, BartC wrote:
>> I need to measure how long short processes take to execute.
>>
>> All the docs point to using QueryPerformanceCounter() (as opposed to
>> using, for example, the RDTSC machine instruction).

>> but the problem is they are inconsistent.
>
> They are consistent, we are using performance counter for fine time
> measurements. The time in seconds is obtained with
> QueryPerformanceFrequency. Ticks do not make sense. 8ms is too short for
> statistically correct measurements, e.g. when your thread loses
> processor it will not return until next 10ms on a busy machine.

Thanks, using QueryPerformanceFrequency I can now convert the QPC result 
to milliseconds.

By using Sleep(N) as the task, I found that QPC gives results that are 
scattered by up to 10 milliseconds, sometimes more (although Sleep() 
seems to have its own considerable overheads when N is small).

I also found that C's clock() function only seems to be updated very 
15msec or so. So maybe, there's a connection.

But by first waiting for a clock() transition, then starting to measure, 
QPC results were more consistent. Not perfect, but I think now more 
usable, and more precise than clock() for these short tasks.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#6670

From"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Date2016-05-29 19:04 +0200
Message-ID<nif7e7$1nvh$1@gioia.aioe.org>
In reply to#6669
On 2016-05-29 18:32, BartC wrote:
> On 29/05/2016 16:16, Dmitry A. Kazakov wrote:
>> On 2016-05-29 11:53, BartC wrote:
>>> I need to measure how long short processes take to execute.
>>>
>>> All the docs point to using QueryPerformanceCounter() (as opposed to
>>> using, for example, the RDTSC machine instruction).
>
>>> but the problem is they are inconsistent.
>>
>> They are consistent, we are using performance counter for fine time
>> measurements. The time in seconds is obtained with
>> QueryPerformanceFrequency. Ticks do not make sense. 8ms is too short for
>> statistically correct measurements, e.g. when your thread loses
>> processor it will not return until next 10ms on a busy machine.
>
> Thanks, using QueryPerformanceFrequency I can now convert the QPC result
> to milliseconds.
>
> By using Sleep(N) as the task, I found that QPC gives results that are
> scattered by up to 10 milliseconds, sometimes more (although Sleep()
> seems to have its own considerable overheads when N is small).

Right, this is the effect of timer resolution. You cannot sleep for less 
than the timer resolution value. Which is 10ms by default. It depends on 
when you call Sleep in relation to the coming timer interrupt. The 
interrupt in effect will cause rescheduling, and that will wake up of 
the thread. So you have +0 to 10ms sleep time. If you called Sleep (0) 
you would have a similar effective sleep time as for Sleep (N) when N < 
Timer resolution. There is some statistical bias towards zero, but that 
is beside the point.

Using timeBeginPeriod you can reduce this to +0..1ms.

> I also found that C's clock() function only seems to be updated very
> 15msec or so. So maybe, there's a connection.

That's right. You should never use Windows system time functions. I 
suppose that clock() calls to the Windows system time API. System time 
is based on the time source derived from the timer, and thus its 
accuracy is 10ms by default, regardless the declared resolution, 
whichever it be.

If you want reliable and accurate time stamps you need to use 
QueryPerformanceCounter with a background thread synchronizing system 
UTC time with the performance counter ticks. It collect the performance 
counter and system time readings, throw out the artifacts caused by 
process switching, and average counter to the system time conversion 
coefficients (e.g. to FILETIME, a 64-bit 100ns resolution time). This is 
not trivial, but doable. This way you can get time stamps of ns 
resolution and accuracy.

I have developed a commercial C++ class library for this purpose. So I 
cannot give you more details regarding the algorithms.

> But by first waiting for a clock() transition, then starting to measure,
> QPC results were more consistent. Not perfect, but I think now more
> usable, and more precise than clock() for these short tasks.

The performance counter has the accuracy of the front bus tact, 
approximately. Which lies in the ns area. The system time has the 
accuracy of the timer interrupt, which is 10ms by default. So feel the 
difference!

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

[toc] | [prev] | [standalone]


Back to top | Article view | comp.programming


csiph-web