![]() |
need your advice on clock()
I'm making a facility to get rid of gpGlobals->time everywhere I can.
This function is supposed to return the time in seconds since the process started, even after the clock() value has overflown. Since I don't want to wait 24 days to check if my function works, could someone tell me if my implementation is correct ? Code:
float ProcessTime (void) |
Re: need your advice on clock()
Since your function is simply counting how many seconds have elapsed, try this instead
Code:
static float time_in_seconds = 0; btw, why won't my code format the way I want it to? :( |
Re: need your advice on clock()
I am under the impression that your code assumes that the difference between current_clock and prev_clock is normally always 1. Is this correct ?
This is not the case, and can't be, because this function can be called anytime and it can elapse minutes (or hours) between two successive calls, and thus the current_clock and prev_clock variables could differ greatly. And time_in_seconds wouldn't have been updated since last call, and thus would be completely obsolete. There may be something I don't understand, but to me it seems your code is heavily buggy :) |
Re: need your advice on clock()
oops, you are right, the code I posted won't work for at least 2 or 3 different reasons 8o
Let's have a look at this one instead :) static float time_in_seconds = 0; static long prev_clock = 0; long current_clock; float time_diff; current_clock = clock(); if (current_clock < prev_clock) { // calculate ticks elapsed up to rollover event time_diff = LONG_MAX - prev_clock; // add on ticks elapsed after rollover event time_diff = time_diff + current_clock + 1; } else time_diff = current_clock - prev_clock; prev_clock = current_clock; time_in_seconds += time_diff / CLOCKS_PER_SEC; return time_in_seconds Note The function MUST be called at least once between every rollover event! DAMN! I still have no idea how to copy/paste code into this thing so it shows up the way I want it to. I need a tutorial or something. |
Re: need your advice on clock()
Your code doesn't format right because you're using tabs as separators... and you can't write tabs in the "post reply" text boxes. I'm not sure there's anything you can do but to change your tabs to spaces...
Back on track, basically all I wanted to know was whether my function would work. Does it ? Assuming it does, what's the advantage of yours over mine ? |
Re: need your advice on clock()
Working with clock ticks is so much fun and so very confusing :)
I like what you've come up with, and you've got me revisting some of my existing "clock" code which probably can be made simpler and faster without losing any precision. Anyhow, I looked over your code (and over) and found some minor things which are very subtle and may not matter much depending on the application, but there's one part which appears to be incorrect. Here goes ... static long current_clock; The above line does not have to be static, however you may gain a performance edge by not allocating stack space for it on each call. This line has a small error in it: time_in_seconds = (float) current_clock / CLOCKS_PER_SEC; After a rollover event, the elapsed time in seconds is actually: time_in_seconds = (float) ( current_clock + 1 ) / CLOCKS_PER_SEC; The extra clock tick is added because the rollover looks like this (assuming a MAX value of 2) Code:
Clock ticks ---> This line I cannot understand: rollover_difference = (float) 286331153 / CLOCKS_PER_SEC * rollover_count; What does 286331153 represent? If we are calculating the number of seconds elapsed during each rollover, then you should be using 2147483647 (2^31 - 1) as the constant (if I typed it in right). You should use the macro LONG_MAX to make the code machine independant. (float) 286331153 / CLOCKS_PER_SEC is an inline division of two constants, you may as well precalculate this. The compiler may do this for you, but it would be cleaner to precalculate elsewhere. You may want to replace the data type "float" with "double" because float does not have enough precision to get exact timing conversions in all cases. The alternative function I posted reduces the number of divisions and multiplications which are computationally more expensive than addition and subtraction, it should reduce precision errors, and it should correct for all the errors I found (I hope anyway). What I'd do next is replace float with double, and turn the function into a fully contained class object. There's probably still some performance improvements to be made in there as well. |
Re: need your advice on clock()
Quote:
Thanks. But instead of adding +1 to current_clock ONLY IF a rollover has happened, I'd rather add 1 to LONG_MAX (sounds more logical) - no worry, LONG_MAX won't overflow, since I'll cast it to (double) beforehand. rollover_difference = ((double) LONG_MAX + 1) / CLOCKS_PER_SEC * rollover_count; Quote:
Quote:
Quote:
good idea, thank you ! Quote:
Thanks a lot for the review, it's much faster when you get your code reviewed by people who have not spent the day with the nose above it, pointing mistakes is so easy :) Tell me if I can give you a hand in return someday :) [edit] Where is LONG_MAX defined ? I can't find this macro anywhere... |
Re: need your advice on clock()
Nevermind, found it - in limits.h
Here's the function now. Code:
float ProcessTime (void) |
Re: need your advice on clock()
Looks much nicer now. You're down to 1 division, one multiplication and one addition per call.
Just one last thing to suggest, since rollovers occure so infrequently, there's a lot of wasted cpu cycles recalcualting rollover * rollover_count for each function call. I suggest that you store the result as static local and update it only after each rollover event. Quote:
You've already helped me several times now!!! I'm just trying to keep pace with you :) |
Re: need your advice on clock()
one other thing - is current_clock, etc. ever negative? it doesn't seem so, therefore why not make those values unsigned longs instead of just longs, and thus get 2^32-1 clock ticks till rollover instead of 2^31-1?
second thing, the return value should probably be a double if you are passing back time_in_seconds, which is a double. |
All times are GMT +2. The time now is 22:28. |
Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.