tags:

views:

135

answers:

3

I was trying to program a Timer class (unaware that boost had one), then when that wasn't working, I tried to just output the value of clock(), using this code:

#include <ctime>
#include <iostream>

int main()
{
 for(int i = 0; i < 50; ++i)
 {
  std::cout << std::clock() << " ";
 }
 return 0;
}

When I run the program, I get a series of 0s. I have a similar experience when using boost thread sleep functions to spread out timing a little longer (although after a few seconds, it jumps from 0 to 10,000 and keeps outputting 10,000).

I'm running Gentoo Linux. Is this a platform thing? A C++ thing? What's going on?

Edit: Strangely the jump to 10000 comes after a number of seconds, not milliseconds. When I was sleeping my thread for a second at a time, it took five or six seconds to get to 10000. However, if I'm understanding correctly. The time the thread spends sleeping doesn't contribute towards the clock() count? (Which would make sense; why would it be executing clock cycles if it's sleeping?)

+2  A: 

The clock() return value is specified in microseconds. But typical granularity of whatever low-level system call the clock() implementation uses is much lower. So it seems that on your system the granularity is 10ms. Also note that clock() does NOT measure real time - it measures CPU time used by the program. So the time flows when your program controls the CPU, and it freezes when your program is suspended - sleeping, for example.

slacker
Note -- it doesn't **have** to be microseconds. (Hence the reason for the CLOCKS_PER_SEC macro)
Billy ONeal
http://www.cplusplus.com/reference/clibrary/ctime/clock/. This says that it is not guaranteed to be any specific unit. You have to use the CLOCKS_PER_SEC macro to find the time in real units. As for 10ms resolution, I think that isn't terribly uncommon.
Merlyn Morgan-Graham
However, in a POSIX-conformant system it *does* have to be microseconds (`CLOCKS_PER_SEC` is mandated to be 1000000).
Tyler McHenry
POSIX mandates CLOCKS_PER_SEC == 1000000. So unless you're on some old wacky OS, it's going to be microseconds :).
slacker
Some of us code for ISO, some for POSIX. I'm not sure that Linux is entirely POSIX-compliant anyway. Linus' attitude to standards compliance was, shall we say, "spotty", at least in the early days (no idea about now). Not that that's a bad thing, most times pragmatism beats dogmatism in the real world :-)
paxdiablo
When the Linux manpage for clock(3) says that POSIX requires CLOCKS_PER_SEC to be 1000000, you can be sure that's because Linux (or more likely glibc) is implementing it that way.
Ken Bloom
I doubt that any libc maker (even Microsoft!) would pass on such low-hanging compatibility fruit like this. Making CLOCKS_PER_SEC equal 1000000 is a trivial way for one more POSIX compatibility-point.
slacker
@slacker - Or one more Posix incompatibility point. Microsoft tries very hard to be incompatible when they think they can use the incompatibility to lock in users.
Omnifarious
@Omnifarious:Oh come on, do you think people coding exclusively for windows would even *use* unixish C APIs like `clock()`? There are a bunch of Win32 APIs that do the same task, while accomplishing the vendor lock-in objective much more effectively. `clock()` is needed to port existing *nix code to windows, not the other way around.
slacker
A: 

std::clock's resolution is unspecified. In most cases, it's resolution is going to be about 10ms. Hence the jump.

Billy ONeal
A: 

Try the following:


#include <ctime>
#include <iostream>

int main()
{
   for(int i = 0; i < 50; ++i)
   {
      for (int j = 0; j < 500; ++j )
      {
         std::cout << j << " ";
      }
      std::cout << std::endl;
      std::cout << std::clock() << std::endl;
   }
   std::cout << std::endl;
   return 0;
}     

On my system, I see the return value of clock() staying at 0 until at some point it jumps to 10000. It stays at 10000 till the end. If I remove the std::cout in the inner loop, the return value of clock() stays at 0 all the way through. Looks like clock() returns values in increments of 10000 only.

If I change the inner loop to compute the square root of j and print the return value of sqrt(), the return value of clock() goes up to 50000, but is still increases in increments of 10000.