www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - realtime HighPerformanceCounter information

reply "nobody_" <spam spam.spam> writes:
Is it possible to get timing information before stopping a timer?

Something like this:

HighPerformanceCounter c = new HighPerformanceCounter();
c.start();
while(c.microseconds()<1000){
pauze();
}
c.stop();

When I do this now, c.microseconds() returns some 'random number :( 
Nov 21 2006
next sibling parent reply Chad J <gamerChad _spamIsBad_gmail.com> writes:
nobody_ wrote:
 Is it possible to get timing information before stopping a timer?
 
 Something like this:
 
 HighPerformanceCounter c = new HighPerformanceCounter();
 c.start();
 while(c.microseconds()<1000){
 pauze();
 }
 c.stop();
 
 When I do this now, c.microseconds() returns some 'random number :( 
 
 

I'm curious, why do you need to keep the timer running?
Nov 21 2006
parent reply "nobody_" <spam spam.spam> writes:
 Is it possible to get timing information before stopping a timer?

 Something like this:

 HighPerformanceCounter c = new HighPerformanceCounter();
 c.start();
 while(c.microseconds()<1000){
 pauze();
 }
 c.stop();

 When I do this now, c.microseconds() returns some 'random number :(

I'm curious, why do you need to keep the timer running?

I hoped to use it for timing my main loop :)
Nov 21 2006
next sibling parent reply Chad J <gamerChad _spamIsBad_gmail.com> writes:
nobody_ wrote:
Is it possible to get timing information before stopping a timer?

Something like this:

HighPerformanceCounter c = new HighPerformanceCounter();
c.start();
while(c.microseconds()<1000){
pauze();
}
c.stop();

When I do this now, c.microseconds() returns some 'random number :(

I'm curious, why do you need to keep the timer running?

I hoped to use it for timing my main loop :)

Hmmm, well unless there are bizarre realtime low-level type conditions that must be met, then I'd suggest doing what Lutger just mentioned - wrap D's timer into your own that allows you to do what you want. Perhaps something like this: class MyTimer { private HighPerformanceCounter hpc; private ulong runningTime = 0; public ulong microseconds() { hpc.stop(); runningTime += hpc.microseconds(); hpc.start(); return runningTime; } public void reset() { hpc.stop(); hpc.start(); runningTime = 0; } this() { hpc = new HighPerformanceCounter(); hpc.start(); } } Now your code becomes something like this: MyTimer timer = new MyTimer(); while( timer.microseconds < 1000 ) { // ... do whatever ... } IMO Phobo's current timer setup is a bit too low level and barely documented for normal use. std.perf is also a poor name for a timing module. It'd be nice to see a timer class/struct similar to the one I just wrote (but much much more feature rich of course) implemented in phobos, perhaps in a seperate std.timer module (which means std.perf can stay as it is, and it probably won't bother anyone).
Nov 21 2006
parent reply "nobody_" <spam spam.spam> writes:
I've just been checking the souce code of  std.perf and I can't see why it 
isn't:

interval_type periodCount()
{
    if(running){
        return m_end - m_start;
    }else{
        QueryPerformanceCounter(&m_inter);
         return m_inter - m_start;
    }
}

If the counter doesn't take any more resources than its starting value, 
stop() can be left out totally
and the code would be as simple as this :)

interval_type periodCount()
{
        QueryPerformanceCounter(&m_inter);
         return m_inter - m_start;
}

If I were into object programming, I might even be able to implement it.
But as I'm not into it, it might just be a bad idea ;)

 Hmmm, well unless there are bizarre realtime low-level type conditions 
 that must be met, then I'd suggest doing what Lutger just mentioned - wrap 
 D's timer into your own that allows you to do what you want.
 Perhaps something like this:

 class MyTimer
 {
 private HighPerformanceCounter hpc;
 private ulong runningTime = 0;

 public ulong microseconds()
 {
 hpc.stop();
 runningTime += hpc.microseconds();
 hpc.start();
 return runningTime;
 }

 public void reset()
 {
 hpc.stop();
 hpc.start();
 runningTime = 0;
 }

 this()
 {
 hpc = new HighPerformanceCounter();
 hpc.start();
 }
 }

 Now your code becomes something like this:

 MyTimer timer = new MyTimer();
 while( timer.microseconds < 1000 )
 {
 // ... do whatever ...
 }

 IMO Phobo's current timer setup is a bit too low level and barely 
 documented for normal use.  std.perf is also a poor name for a timing 
 module.  It'd be nice to see a timer class/struct similar to the one I 
 just wrote (but much much more feature rich of course) implemented in 
 phobos, perhaps in a seperate std.timer module (which means std.perf can 
 stay as it is, and it probably won't bother anyone). 

Nov 21 2006
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
nobody_ wrote:
 I've just been checking the souce code of  std.perf and I can't see why it 
 isn't:
 
 interval_type periodCount()
 {
     if(running){
         return m_end - m_start;
     }else{
         QueryPerformanceCounter(&m_inter);
          return m_inter - m_start;
     }
 }
 
 If the counter doesn't take any more resources than its starting value, 
 stop() can be left out totally
 and the code would be as simple as this :)
 
 interval_type periodCount()
 {
         QueryPerformanceCounter(&m_inter);
          return m_inter - m_start;
 }

periodCount does not return the time, but the number of ticks. To get the time in seconds you have to divide by the frequency, which is represented by sm_freq in std.perf. The other stuff is for adjusting to milli- and microseconds and not getting rounding errors. I believe this (HighPerformanceCounter) is windows-only code though.
 If I were into object programming, I might even be able to implement it.
 But as I'm not into it, it might just be a bad idea ;)

Or not, it might just be simple and fun to do. A timer could very well be a single tiny function that returns the time since application was loaded or whatever, no object orientation needed at all.
Nov 21 2006
parent "nobody_" <spam spam.spam> writes:
"Lutger" <lutger.blijdestijn gmail.com> wrote in message 
news:ek0eqg$cns$1 digitaldaemon.com...
 nobody_ wrote:
 I've just been checking the souce code of  std.perf and I can't see why 
 it isn't:

 interval_type periodCount()
 {
     if(running){
         return m_end - m_start;
     }else{
         QueryPerformanceCounter(&m_inter);
          return m_inter - m_start;
     }
 }

 If the counter doesn't take any more resources than its starting value, 
 stop() can be left out totally
 and the code would be as simple as this :)

 interval_type periodCount()
 {
         QueryPerformanceCounter(&m_inter);
          return m_inter - m_start;
 }

periodCount does not return the time, but the number of ticks. To get the time in seconds you have to divide by the frequency, which is represented by sm_freq in std.perf. The other stuff is for adjusting to milli- and microseconds and not getting rounding errors.

I know what periodCount is for :) As it is used by milliseconds etc, you only have to change that function.
 I believe this (HighPerformanceCounter) is windows-only code though.

 If I were into object programming, I might even be able to implement it.
 But as I'm not into it, it might just be a bad idea ;)

Or not, it might just be simple and fun to do. A timer could very well be a single tiny function that returns the time since application was loaded or whatever, no object orientation needed at all.

I meant I wasn't sure about my capabilities of reading the code :)
Nov 22 2006
prev sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
nobody_ wrote:
Is it possible to get timing information before stopping a timer?

Something like this:

HighPerformanceCounter c = new HighPerformanceCounter();
c.start();
while(c.microseconds()<1000){
pauze();
}
c.stop();

When I do this now, c.microseconds() returns some 'random number :(

I'm curious, why do you need to keep the timer running?

I hoped to use it for timing my main loop :)

Actually... you don't have to do anything. The implementation of .close() does nothing but query for the current counter state and store it. Repeated calls to .close(), therefore, will equate to repeated re-queries to the counter, with all calls to .*seconds() in between doing their math on the same original .start() result. So... you already have what you want. Just make sure to call .close() once before calling the .*seconds() methods. (At least on Windows... I admit to not checking the linux impl.) -- Chris Nicholson-Sauls
Nov 21 2006
next sibling parent "nobody_" <spam spam.spam> writes:
"Chris Nicholson-Sauls" <ibisbasenji gmail.com> wrote in message 
news:ek0i74$fn3$1 digitaldaemon.com...
 nobody_ wrote:
Is it possible to get timing information before stopping a timer?

Something like this:

HighPerformanceCounter c = new HighPerformanceCounter();
c.start();
while(c.microseconds()<1000){
pauze();
}
c.stop();

When I do this now, c.microseconds() returns some 'random number :(

I'm curious, why do you need to keep the timer running?

I hoped to use it for timing my main loop :)

Actually... you don't have to do anything. The implementation of .close() does nothing but query for the current counter state and store it. Repeated calls to .close(), therefore, will equate to repeated re-queries to the counter, with all calls to .*seconds() in between doing their math on the same original .start() result. So... you already have what you want. Just make sure to call .close() once before calling the .*seconds() methods. (At least on Windows... I admit to not checking the linux impl.) -- Chris Nicholson-Sauls

Hmm.. thanks! But I still think that a query (count, micro, milli etc) should be used c.stop c.milliseconds Where: c.milliseconds should be enough, I think. It won't really change anything,except be a little be intuitive :) But anyway, thanks.
Nov 22 2006
prev sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Chris Nicholson-Sauls wrote:
 Actually... you don't have to do anything.  The implementation of 
 .close() does nothing but query for the current counter state and store 
 it.  Repeated calls to .close(), therefore, will equate to repeated 
 re-queries to the counter, with all calls to .*seconds() in between 
 doing their math on the same original .start() result.
 
 So... you already have what you want.  Just make sure to call .close() 
 once before calling the .*seconds() methods.  (At least on Windows... I 
 admit to not checking the linux impl.)
 
 -- Chris Nicholson-Sauls

Ah yes, sorry for the misinformation. It's little counter intuitive for me. I didn't see any linux implementation of HighPerformanceCounter.
Nov 22 2006
prev sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
nobody_ wrote:
 Is it possible to get timing information before stopping a timer?
 
 Something like this:
 
 HighPerformanceCounter c = new HighPerformanceCounter();
 c.start();
 while(c.microseconds()<1000){
 pauze();
 }
 c.stop();
 
 When I do this now, c.microseconds() returns some 'random number :( 
 
 

It is not possible as is, but you could wrap it in a function yourself that stops, get's the results and then starts again. Perhaps they even get inlined? Other than that the code is pretty straightforward to rip out and make this change yourself.
Nov 21 2006