Clock Troubles

This is a discussion on Clock Troubles within the C Programming forums, part of the General Programming Boards category; I appear to be having trouble with clock(). I need to get precise time measurements (milliseconds would be nice, but ...

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    6

    Clock Troubles

    I appear to be having trouble with clock(). I need to get precise time measurements (milliseconds would be nice, but I understand that that is not universally possible) and I would like to remain operating system unspecific. I decided to use clock(), but it has not been working as advertised.

    The output of the following program is simply '0'. Yet when I increase the size of the for loop, the value becomes positive -- but is always an even number of seconds. Apparently, clock() is acting as if it has a resolution of seconds or worse. What do I do to make this work?

    Code:
      1 #include <stdio.h>
      2 #include <time.h>
      3 
      4 int main(int argc, char** argv)
      5 {
      6     clock_t a = clock();
      7     int i; for(i = 0; i < 10000; i++);
      8     clock_t b = clock();
      9     printf("%f\n",(double)(b-a));
     10     return 0;
     11 }

  2. #2
    Registered User Swarvy's Avatar
    Join Date
    Apr 2008
    Location
    United Kingdom
    Posts
    195
    Quote Originally Posted by _Nate_ View Post
    I appear to be having trouble with clock(). I need to get precise time measurements (milliseconds would be nice, but I understand that that is not universally possible) and I would like to remain operating system unspecific. I decided to use clock(), but it has not been working as advertised.

    The output of the following program is simply '0'. Yet when I increase the size of the for loop, the value becomes positive -- but is always an even number of seconds. Apparently, clock() is acting as if it has a resolution of seconds or worse. What do I do to make this work?

    Code:
      1 #include <stdio.h>
      2 #include <time.h>
      3 
      4 int main(int argc, char** argv)
      5 {
      6     clock_t a = clock();
      7     int i; for(i = 0; i < 10000; i++);
      8     clock_t b = clock();
      9     printf("%f\n",(double)(b-a));
     10     return 0;
     11 }
    You need to use the macro CLOCKS_PER_SEC

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >Apparently, clock() is acting as if it has a resolution of seconds or worse. What do I do to make this work?
    The following would print out seconds elapsed, so you could add this after the first printf():
    Code:
        printf("&#37;f\n",(double)(b-a)/CLOCKS_PER_SEC);
    The loop probably executes almost instantaneously. In fact the compiler may even optimise it out, since it's not doing any useful work. I think there's a POSIX function called ftime(), which has a milliseconds field.

  4. #4
    Registered User
    Join Date
    May 2008
    Posts
    6
    Why does dividing by CLOCKS_PER_TICK help?

    Also, I too thought that the compiler might be optimizing the loop out -- but as I said, you jack the size of the loop high enough, and the program prints something like '3000' or '4000' -- but any less than that, and it's right back to '0' -- no intermediary values.

  5. #5
    Registered User
    Join Date
    Jan 2008
    Posts
    182
    Its CLOCKS_PER_SEC, not CLOCKS_PER_TICK.

    http://www.acm.uiuc.edu/webmonkeys/b....15.html#clock

  6. #6
    Registered User
    Join Date
    Jan 2008
    Posts
    182
    From the example I gave you, I think its more efficient to do this:

    Code:
    #include <time.h>
    #include <stdio.h>
    
    int main(void)
    {
    	clock_t ticks1, ticks2;
    	
    	ticks1 = clock();
    	ticks2 = ticks1;
    	while( ticks2 - ticks1 < CLOCKS_PER_SEC)
    		ticks2=clock();
    
    	printf("Took &#37;ld ticks to wait one second. ticks2 = %ld, ticks1 = %ld\n",ticks2 - ticks1, ticks2, ticks1);
    	printf("This value should be the same as CLOCKS_PER_SEC which is %ld.\n",CLOCKS_PER_SEC);
    	return 0;
    }
    This way, you'll be sure that the while loop will take exactly 1 second if ticks1 is some other random, relatively big number like 264.
    Last edited by samus250; 06-17-2008 at 09:04 PM.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    There is nothing wrong with the original code posted (it would show the number of clock-ticks, so dividing by CLOCKS_PER_SEC would give the time in seconds).

    The problem with the time being zero is either that the time of that loop is so short that it's not registering even one tick - make the loop longer. But it may well be that the compiler removes the empty loop as it's not actually doing anything.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    FOSS Enthusiast
    Join Date
    Jun 2008
    Location
    Germany
    Posts
    64
    Quote Originally Posted by _Nate_ View Post
    but is always an even number of seconds. Apparently, clock() is acting as if it has a resolution of seconds or worse.
    clock() measures the ticks that have passed since program start. The interval of the ticks however depends on the resolution of the operating system's timer.
    I don't know what the frequency is on Windows, but I guess it'll be between 250 and 500Hz.
    500Hz would mean that a tick occurs every 2ms, 250Hz means a tick every 4ms. So it'll probably be enough for measuring ms, but it will not be too acurately though

  9. #9
    Registered User
    Join Date
    May 2008
    Posts
    6
    So what would be the best way going about getting millisecond precision?

  10. #10
    Registered User
    Join Date
    Jan 2008
    Posts
    182
    Quote Originally Posted by matsp View Post
    There is nothing wrong with the original code posted (it would show the number of clock-ticks, so dividing by CLOCKS_PER_SEC would give the time in seconds).

    The problem with the time being zero is either that the time of that loop is so short that it's not registering even one tick - make the loop longer. But it may well be that the compiler removes the empty loop as it's not actually doing anything.

    --
    Mats
    Code:
    #include <time.h>
    #include <stdio.h>
    #include <windows.h>
    
    int main(void)
    {
    	clock_t ticks1, ticks2;
    	
    	Sleep(265);
    	ticks1 = clock();
    	ticks2 = ticks1;
    	while((ticks2/CLOCKS_PER_SEC-ticks1/CLOCKS_PER_SEC)<1)
    		ticks2=clock();
    
    	printf("Took %ld ticks to wait one second. ticks2 = %ld, ticks1 = %ld\n",ticks2 - ticks1, ticks2, ticks1);
    	printf("This value should be the same as CLOCKS_PER_SEC which is %ld.\n",CLOCKS_PER_SEC);
    	return 0;
    }
    That code is weird, notice the windows Sleep function I put there. When I sleep for 265 miliseconds, ticks1 will be 265, so will ticks2 (lines 10 and 11). This is my output:

    Code:
    Took 735 ticks to wait one second. ticks2 = 1000, ticks1 = 265
    This value should be the same as CLOCKS_PER_SEC which is 1000.
    Apparently, the loop breaks when ticks2 is 1000, and it took 735 ticks to wait one second, which is not true because CLOCKS_PER_SEC is 1000 in my computer.

    Now, if I do it the way I put it, it works. And if I remove the Sleep() function, it also works. But If the program had some time running, then it doesn't work.

  11. #11
    Registered User
    Join Date
    Jan 2008
    Posts
    182
    Oh and question: The size of clocks_t is 4 bytes... what if the program has been running longer than what fits in the variable?

  12. #12
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by samus250 View Post
    Code:
    #include <time.h>
    #include <stdio.h>
    #include <windows.h>
    
    int main(void)
    {
    	clock_t ticks1, ticks2;
    	
    	Sleep(265);
    	ticks1 = clock();
    	ticks2 = ticks1;
    	while((ticks2/CLOCKS_PER_SEC-ticks1/CLOCKS_PER_SEC)<1)
    		ticks2=clock();
    
    	printf("Took %ld ticks to wait one second. ticks2 = %ld, ticks1 = %ld\n",ticks2 - ticks1, ticks2, ticks1);
    	printf("This value should be the same as CLOCKS_PER_SEC which is %ld.\n",CLOCKS_PER_SEC);
    	return 0;
    }
    That code is weird, notice the windows Sleep function I put there. When I sleep for 265 miliseconds, ticks1 will be 265, so will ticks2 (lines 10 and 11). This is my output:

    Code:
    Took 735 ticks to wait one second. ticks2 = 1000, ticks1 = 265
    This value should be the same as CLOCKS_PER_SEC which is 1000.
    Apparently, the loop breaks when ticks2 is 1000, and it took 735 ticks to wait one second, which is not true because CLOCKS_PER_SEC is 1000 in my computer.

    Now, if I do it the way I put it, it works. And if I remove the Sleep() function, it also works. But If the program had some time running, then it doesn't work.
    The result is correct. If I understand correctly the error is

    ticks2/CLOCKS_PER_SEC-ticks1/CLOCKS_PER_SEC

    you would want this:

    (ticks2-ticks1)/CLOCKS_PER_SEC

    Since clock_t seems to be a long integer (according to your code) you will have:

    ticks1/CLOCKS_PER_SEC == 265/1000 == 0

    I suppose you had in mind that icks1/CLOCKS_PER_SEC == 0.265

    Right?

  13. #13
    Registered User
    Join Date
    Jan 2008
    Posts
    182
    Thanks, I knew that the problem was the non floating point division, that's why I posted the other code (see a couple of posts above). The thing is that I was looking at ticks2, and never thought about looking and ticks1 hehe. That is the reason why the loop breaks when ticks2 is 1000, because the calculation truncates the decimal part of the number. So its like saying that ticks1/1000 is 0, not .265.

    Thanks for clearing my mind.

    But, about my second question. What would happen if the program has been running for longer than what fits in the variable?

    EDIT: This is the output now, using while((ticks2 - ticks1) / CLOCKS_PER_SEC < 1)
    Code:
    Took 1000 ticks to wait one second. ticks2 = 1265, ticks1 = 265
    This value should be the same as CLOCKS_PER_SEC which is 1000.
    Last edited by samus250; 06-18-2008 at 09:43 PM.

  14. #14
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Well, a long integer, I believe is 4,294,967,296 on an Intel CPU. Which means 4bytes. Divide that by 1000 you have 4,294,967 seconds which is 1193 hours. I don't think a program will run for that much

    In any case it will just overflow giving wrong results. Maybe starting from 0 again...

    EDIT: well, half that amount since it is probably signed

  15. #15
    Registered User
    Join Date
    Jan 2008
    Posts
    182
    Quote Originally Posted by C_ntua View Post
    Well, a long integer, I believe is 4,294,967,296 on an Intel CPU. Which means 4bytes. Divide that by 1000 you have 4,294,967 seconds which is 1193 hours. I don't think a program will run for that much

    In any case it will just overflow giving wrong results. Maybe starting from 0 again...

    EDIT: well, half that amount since it is probably signed
    OK so its about 25 days...
    Another question: How does the Sleep function work? The code I put (with that while loop) uses 50% processor power (I'm in hyper threading so that's like saying 100%). Any idea of how to make a sleep function that does not draw 100% cpu power?

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Logical Error in Clock program
    By SVXX in forum C++ Programming
    Replies: 0
    Last Post: 05-10-2009, 01:12 AM
  2. Outside influences on clock cycles? (clock_t)
    By rsgysel in forum C Programming
    Replies: 4
    Last Post: 01-08-2009, 06:15 PM
  3. clock program
    By bazzano in forum C Programming
    Replies: 3
    Last Post: 03-30-2007, 11:12 PM
  4. world clock
    By nevermind in forum C++ Programming
    Replies: 1
    Last Post: 10-23-2002, 08:45 AM
  5. ANN: The Fourth Contest: Alarm Clock, sign up here
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 59
    Last Post: 08-10-2002, 01:24 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21