Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.programming > #6667 > unrolled thread
| Started by | BartC <bc@freeuk.com> |
|---|---|
| First post | 2016-05-29 10:53 +0100 |
| Last post | 2016-05-29 19:04 +0200 |
| Articles | 4 — 2 participants |
Back to article view | Back to comp.programming
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
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-05-29 10:53 +0100 |
| Subject | Time 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]
| From | "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> |
|---|---|
| Date | 2016-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