Archived

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

vanillacoke

Timers

Recommended Posts

I also use timeGetTime. It is supposedly faster and more accurate than GetTickCount. If you are profiling or something else that needs much smaller time intervals (I am avoiding both the words precision and accurate) there are QueryPerformanceCounter and QueryPerformanceFrequency which are WIN32 API functions (ugh...). They are used together and deliver in the millionth of a second range. Check out the MSDN (ugh...) or the OpenGL SuperBible (chapt 19) if you have it. Lastly, there is the Intel Pentium RDTSC (Read Time Stamp Counter) assembly instruction. It can beat out readings in the 5 nano second range, so I''ve heard. I''ve seen a class wrapper using it. Might be good for something, but it''s obviously not portable. If you ask me, I will post some code for the wrapper class, or somebody else can do it before me if they know how. I may not reply until after the 4th, though (Yippeeee! Fireworks! I bought $90 worth. BOOM!)

Share this post


Link to post
Share on other sites
Click search, and wait. Then wait again. It takes time, but it usually ends up giving the results.

It took me longer to find a good thread than it would have taken to write a good answer. But I couldn''t resist doing it again

Cédric

Share this post


Link to post
Share on other sites
Well, here''s your little timer class - even though you didn''t ask for it. I wouldn''t recommend using it for anything except profiling becuase I don''t think it will work on an Athlon.
//  timer.h
// By Gauler The Goat
// Can''t take credit, though.
// Just copied from a book.
#pragma once

class timer {
unsigned __int64 start, overhead;

public:

timer ();
void Start ();
unsigned __int64 Stop ();
unsigned __int64 Overhead () {return overhead;}
};

// timer.cpp
// By Gauler The Goat
// Can''t take credit, though.
// Just copied from a book.
#include "timer.h"

inline unsigned __int64 asmRDTSC ()
{
__asm _emit 0x0F __asm _emit 0x31
}

timer::timer () :overhead (0)
{
Start ();
overhead = Stop ();
}

void timer::Start () {start = asmRDTSC ();}
unsigned __int64 timer::Stop () {return asmRDTSC () - start - overhead;}
Let''s try to explain this... The pragma once does the same thing as header guards it just makes sure the header is only included once. Slick. The class uses __int64 which are 64 bit data types build into MSVC and most other compilers. In timer.cpp, the asmRDTSC function uses the asm instruction rdtsc by inserting the actual instruction code into the program. It''s done this way because on MSVC6 the assembler is not aware of the rdtsc instruction. Also, I didn''t do it here, but I have seen some people put a dummy command like
__asm xor eax,eax __asm xor edx,edx 
before calling rdtsc. Why? So that the compiler knows that the eax and edx registers are being modified. That being said,
__asm _emit 0x0F __asm _emit 0x31 
puts the upper dword of the clock cycles passed since the CPU loaded into the edx register and the lower dword into eax. You will get a compiler warning that the function does not return anything (unless you put in those dummy instructions modifying eax and edx), but it does because the way that cdecl functions return __int64 is to put the high dword in edx and the low dword in eax. Spiffy. The rest should be pretty understandable. You must know, however, that the "timer" measures clock cycles, not a time unit. To convert these to time units, you must know your processer speed. You can find this out by timing one second like this:
unsigned __int64 GetConversion (void)
{
timer t;
t.Start ();
Sleep (1000);
return t.Stop ();
}
although you will inevitably lose a relatively large amount of accuracy, it is unavoidable. Divide this result by 1 million to get the speed of your machine in mhz and you can then use that as a conversion factor. Hope this is cool. I should note that the code is from a book by Feng Yuan execpt for some style modifications.

Share this post


Link to post
Share on other sites