Archived

This topic is now archived and is closed to further replies.

High performance counter

This topic is 5530 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hope this is related to theme of this forum! I''ve recently started using the high-resolution performance counter the QueryPerformanceFrequency() funtion uses in MSVC++, but what is the speed of this counter dependent on? Is it the CPU or the motherboard, also, i''ve got an 800MHz Duron and my counter iterates 1,193,180 times per second. How does this compare with other processors?

Share this post


Link to post
Share on other sites
well, help files say "The value of the count is processor dependent. On some processors, for example, the count might be the cycle rate of the processor clock. "

and i get the same value as you(1193180) on my PIII 500, so its obviously nothing to do with cpu manufacturer/speed



Runicsoft -- home of my open source Function Parser and more

Share this post


Link to post
Share on other sites
It depends on the type of system as well as the type of processor. The counter reports a frequency of 450990000 on my dual Pentium III 450 MHz system.

[edited by - spock on October 19, 2002 10:53:20 PM]

Share this post


Link to post
Share on other sites
It''ll probably depend on the motherboard chip-set more than anything else (processor class as well).

For APi586 class processors, you can the assembly instruction rdtsc, which returns the current CPU ticks in eda:eax. This is highly dependany on the clock-rate. There are several ways to time the clock-rate, and you can use that as a divisor to calculate elapsed time very accurately & precisely.

Share this post


Link to post
Share on other sites
Cheers for the replys guys. I see, but this rdtsc instruction returns a value with a high and low order part, anyone recommend a text on how to convert it to a ''standard'' long integer?

Share this post


Link to post
Share on other sites
quote:
Original post by johndunne
how to convert it to a 'standard' long integer?


Well, you shouldn't do that because the full precision of the counter will overflow a 32-bit unsigned long very quickly. Use the full 64 bits instead. Many compilers have extended types for 64-bit integer arithmetic - in MSVC you can use __int64, for example.


[edited by - spock on October 20, 2002 7:16:27 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by johndunne
...this rdtsc instruction returns a value with a high and low order part, anyone recommend a text on how to convert it to a ''standard'' long integer?


I would recommend reading this post . You simply multiply the value stored in edx by 2^32 and add it to the value stored in eax (although this is not possible on a 32-bit cpu). A 32-bit word like eax consists of 32 bits (!). Since the value that is returned is a 64-bit value the "most significant" bits are stored in edx while the "least significant" bits are stored in eax.

Let''s take an example:

If we have the number 13243546 and we want to write it on a small piece of paper but the pieces are very small it might mot be possible to write all eight digits on the same piece. Instead we could write 1324 on on piece and call these digits the most significant digits and write 3546 on another piece and call these digits the least significant digits. This is more or less what the cpu does when a MUL, DIV or rdtsc instruction is executed. The only difference is that the computer uses binary digits (=bits) and store the digits in so-called latches instead of writing it down on ridiculously small pieces of paper.

Share this post


Link to post
Share on other sites
quote:

how to convert it to a ''standard'' long integer?



You can only do that if the value in edx:eax can fit into a long integer in which case you simply use the value in eax (and clear the sign bit if the long integer is signed) and discard the value in edx.

Share this post


Link to post
Share on other sites
Back to the original question:
I''ve seen QPC use the PIT and the PCI clock (frequencies of 1.193 MHz and 3.580 MHz).

using rdtsc gives you awesome resolution, but it jitters a bit, and you get all sorts of problems on multiprocessor / mobile systems.

Share this post


Link to post
Share on other sites
cheers guys, thats helped loads! In addition, i''ve checked out the high performance counter on a 133Mhz Pentium (overclocked to 150 though) and it reports 1193180 iterations per second too! Ouch, i''m utterly confused!

Share this post


Link to post
Share on other sites
PIT == 8254 timer
Basically it''s a 16 bit counter running at 1.193 MHz (wacky freq = original PC system clock / 12, so IBM saved a crystal. Thanks, guys)
It can be made to emit a regular interrupt (freq = input freq / divisor); div == 64k yields the infamous 18.2 Hz tick rate.
What QPC does is just read the counter.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
The frequency of the performance counter isn''t what matters. When doing calculations with it, you need to do all calculations in relation to QueryPerformanceFrequency. This allows you to base all your calculations per millisecond or per second. Anything below a (lets say..) 100''th of a millisecond is pretty much useless as you cannot query the performance counter fast enough anyways.

As for the Calculations, you can just use the 64bit values on pretty much any pentium system. Although they are 32 bit, they can add/sub/etc a 64 bit value atomically. Typically you''ll be using the performance counter values to calculate deltas, in which case you can typically cast them into 32 bit values without any loss of data.

Share this post


Link to post
Share on other sites