clock() function

  • Thread starter Pushkar Pradhan
  • Start date
D

Daniel Vallstrom

Because this is what the standard actually says:

If the processor time used is not available or its value cannot
^^^^^^^^^^^^^^^^^^^
be represented, the function returns the value (clock_t)(-1)
^^^^^^^^^^^^^^

Yeah, from our favorite legalistic point of view that would be the
thing to hope for. I forgot;p

Daniel Vallstrom
 
J

Jeffrey D. Smith

Keith Thompson said:
On one system I tested yesterday (Solaris 8), clock_t is a 32-bit
signed integer type. The values returned by the clock() function wrap
around to negative values. That's far more useful than returning -1
after 2147 seconds, but it looks like it violates the standard.

As long as it doesn't wrap to (clock_t)(-1), then it is fine. You'll
likely want to cast it to unsigned of the same size. If you detect
a clock() result of (clock_t)(-1), then all bets are off.

For a 32-bit clock_t type, you are stuck with 32-bit resolution
unless there is also a non-standard library call than can return
the number of wrap-arounds since the last call to clock(). (Thus,
effectively increasing the size to 64-bits.)
Probably be best solution in this case would be to make clock_t a
64-bit type (as it already is on some platforms).

That is probably a better solution that would conform
to the standard.
 
D

Daniel Vallstrom

Mike Wahler said:
Should I understand this to mean that the 'wrapping'
to zero described by the documentation posted by OP
is not an allowed 'implementation-defined' component
of 'clock()' behavior?

No. Read the whole clock() description. Dan even explicitly say
in the text you quote above that almost anything goes since it
can be argued that it's "the implementation's best approximation".
He just *hopes* that implementations return -1 since a literal
reading perhaps suggests that. An other approach, and IMO better,
would be to note that wraparounds could be legal, that they are
more useful and common practice, and therefor use wraparounds.

Compare e.g. with the issue if implementations are allowed to
return memory back to the OS (which IMO they certainly are).
You have to make up your own mind.
"Zero" might not be of any
practical use, but perhaps it *could* be called
"best approximation" rather than "not representable".

Are saying that a 'clock()' which "wraps" to zero is
definitely not standard conforming?

The clock type is often signed and then it would wrap to e.g. -2^31.
Anyway, I bet that most or all of the compilers you consider
conforming do wraparounds.


Daniel Vallstrom
 
D

Dan Pop

In said:
Yeah, from our favorite legalistic point of view that would be the
thing to hope for. I forgot;p

It's also from a practical point of view. Imagine that the second clock_t
value you obtain is greater than the first one: how can you tell whether
wraparound occured and how many times between the two clock_t calls?

What is better: no answer or a hopelessly wrong answer?

Dan
 
D

Daniel Vallstrom

It's also from a practical point of view. Imagine that the second clock_t
value you obtain is greater than the first one: how can you tell whether
wraparound occured and how many times between the two clock_t calls?

By requiring that clock calls are made frequent enough. In the OP's
case he would have to call the clock time-out library function at
least every 36 or 72 minutes.
What is better: no answer or a hopelessly wrong answer?

No answer is much better than a possibly wrong answer if the risk of
answering wrong is high enough. But that's not the case here. In all
programs I have used wraparounds in, there is no real risk of missing
a (relevant) wraparound.

Though, perhaps the implementors of clock did wraparounds because it
was the easiest solution rather than something thought through. And
then the standard writers felt that they had to allow the practice?


Daniel Vallstrom
 
D

Dan Pop

In said:
By requiring that clock calls are made frequent enough. In the OP's
case he would have to call the clock time-out library function at
least every 36 or 72 minutes.

How frequent is "frequent enough" in a *portable* program? Is the
standard preventing an implementation from wrapping around after 1 second?
After 1 millisecond?
No answer is much better than a possibly wrong answer if the risk of
answering wrong is high enough. But that's not the case here. In all
programs I have used wraparounds in, there is no real risk of missing
a (relevant) wraparound.

Is this a property of the programs (see my remark above) or of the
actual implementations you have used?
Though, perhaps the implementors of clock did wraparounds because it
was the easiest solution rather than something thought through. And
then the standard writers felt that they had to allow the practice?

The C standard certainly tried to accomodate existing practice, but it
also did its best to discourage wraparounds.

Dan
 
D

Daniel Vallstrom

How frequent is "frequent enough" in a *portable* program? Is the
standard preventing an implementation from wrapping around after 1 second?
After 1 millisecond?

I have only claimed that it's "fairly portable" (which might
be a contradiction in terms). What do you propose if someone
needs large clock timings? I could try some non-C solution
which I don't know how to do and which probably would be
system specific and limited? Or I could fairly easily code
some C module to keep track of the wraparounds and which
will work on all systems I'm coding for.
Is this a property of the programs (see my remark above) or of the
actual implementations you have used?

Both. From the C compiler/system you need that it really
uses wraparounds and that the wraparounds don't occur too
frequently. Then you have to check the clock frequently
enough in the code that needs the timers. It's also
dependent on the input to the program.

This obviously isn't a perfect solution but for me at
least it seemed better than the alternative --- but
that might be because I'm too ignorant of what the
alternative would be.


Daniel Vallstrom
 
D

Dan Pop

In said:
I have only claimed that it's "fairly portable" (which might
be a contradiction in terms). What do you propose if someone
needs large clock timings?

The best solution is to remove the need for large clock timings. It has
always worked for me.
I could try some non-C solution
which I don't know how to do and which probably would be
system specific and limited?

Your own solution is implementation-specific and limited, even if it only
uses standard library functions.

Yes, when the standard library provides no satisfactory solution, there
is nothing wrong with using an implementation-specific solution.
Or I could fairly easily code
some C module to keep track of the wraparounds and which
will work on all systems I'm coding for.

This being comp.lang.c, a solution is considered portable when it relies
only on that the C specification guarantees. Or the C specification
not only doesn't guarantee wraparounds, it even does its best to outlaw
them.

Furthermore, if you detect wraparound, how do you handle it in a
*portable* way, without knowing the range and signedness of clock_t?
Both. From the C compiler/system you need that it really
uses wraparounds and that the wraparounds don't occur too
frequently.

You need more than that. You also need the range of clock_t, which
neither the standard nor the implementation specifies (in a portable way).
Then you have to check the clock frequently
enough in the code that needs the timers.

Frequent checks alter the measurement, because they consume CPU time,
too.
This obviously isn't a perfect solution but for me at
least it seemed better than the alternative --- but
that might be because I'm too ignorant of what the
alternative would be.

The best alternative is to reduce the time interval being measured to
a reasonable value (usually something between 1 second and 10 minutes).
If this is really not possible, implementations usually provide timing
tools without the shortcomings of clock().

Dan
 
D

Daniel Vallstrom

The best solution is to remove the need for large clock timings. It has
always worked for me.

Sometimes that might not be possible though. E.g. I use large clock
timings in a SAT solver. The solver might get hard problems to solve and a
large time limit. More importantly one might want to try different solver
strategies a certain amount of time dependent on the total time limit.

Your own solution is implementation-specific and limited, even if it only
uses standard library functions.

Agreed all along.

Yes, when the standard library provides no satisfactory solution, there
is nothing wrong with using an implementation-specific solution.

But the question is what is best, the C or non-C solution. As you
have pointed out the C solution makes many shady assumptions about
various things not guaranteed by the standard. But it might still be
preferable over a non-C solution if you for every actual effort to
support long clock timings for some system in a non-C way note that
the C solution would have worked just fine again.

I'm not necessarily advocating the C solution, since it's unsafe. But
if you can live with the unsafeness, the C solution might be much
easier than a non-C one, especially once you have some code for
handling long clock times.

This being comp.lang.c, a solution is considered portable when it relies
only on that the C specification guarantees. Or the C specification
not only doesn't guarantee wraparounds, it even does its best to outlaw
them.

Furthermore, if you detect wraparound, how do you handle it in a
*portable* way, without knowing the range and signedness of clock_t?

I'm not of course. IIRC I just tested for some typical cases and handled
them. Actually probably only the common 32 bits type, for both signed and
unsigned. For other clock_t types, the clock timing would only be accurate
until a wrap around occurs.

You see, it's getting worse for every question you ask;)

You need more than that. You also need the range of clock_t, which
neither the standard nor the implementation specifies (in a portable way).

Yup.

Frequent checks alter the measurement, because they consume CPU time,
too.

'Frequently enough' doesn't mean frequent. Typically just at least once
every 32 minutes. One would of course profile the program and make
sure that the clock checks take an insignificant amount of time.


Daniel Vallstrom
 
G

goose

I'm afraid that this is not possible at all (in a portable manner) because
there is no connection whatsoever between the times returned by these two
functions.

no, there isn't. but it is possible, at the start of the program,
to *establish* a point of reference for the 2 tmies returned by
these functions. once you have a base reference, and you know
how many times clock() wraps around in a certain time interval,
(say, once every 36 mins), then you can always use time(), check
if the return minus the last return of time() is greater than
the wraparound time, and then use clock() to get the finer granularity.

its not clean, its not neat, but it is possible, no ?
Feel free to prove me wrong, by posting your code ;-)

if i still had it, i would :)

of course, as it was written a long time ago, it might have
used a platform function anyway, or made assumptions about
the platform. if i had the time, i'd try to write it again.

goose,
 
D

Dan Pop

In said:
no, there isn't. but it is possible, at the start of the program,
to *establish* a point of reference for the 2 tmies returned by
these functions.

What do you mean?
once you have a base reference, and you know
how many times clock() wraps around in a certain time interval,
(say, once every 36 mins), then you can always use time(), check

If your code is relying on such information, then it is no longer
portable.
if the return minus the last return of time() is greater than
the wraparound time, and then use clock() to get the finer granularity.

There is NO way to combine time() and clock(), as they return completely
different times. Imagine that your program is running together with 9
other programs, all 10 being CPU-bound. The time interval reported by
time() will be about 10 times as large as the time interval reported by
clock().

Things are even hairier if the system load is variable during the
interval (which is quite common in practice, when sharing a system with
other people).
its not clean, its not neat, but it is possible, no ?

Is it? You have produced no *valid* argument and no code.

Dan
 
G

Gordon Burditt

yes. if you want more than that at the resolution that clock()
What do you mean?


If your code is relying on such information, then it is no longer
portable.


There is NO way to combine time() and clock(), as they return completely
different times. Imagine that your program is running together with 9
other programs, all 10 being CPU-bound. The time interval reported by
time() will be about 10 times as large as the time interval reported by
clock().

You don't need to combine them. Check clock() and time() periodically.
Compute the difference between the last call to clock() and this
one, and add it to a running sum in a variable with enough range
to handle the sum with reasonable precision and range (e.g. long
double, or use a bignum package). Compute the difference between
the last call to time() and this one. If it's longer than the
fastest possible wraparound time (e.g. 36 minutes above), you *MIGHT*
have blown it and your result should be considered possibly inaccurate.
If it's not, you should have reasonable accuracy.
Things are even hairier if the system load is variable during the
interval (which is quite common in practice, when sharing a system with
other people).

In the above situation it doesn't get hairier, but you might
actually get an accurate answer even if you're not sure it is accurate.

Now, about computing the wraparound time: you know that difftime()
returns the difference of two times in units of seconds, and you
know that the difference of two clock_t values is in units of
(1.0/CLOCKS_PER_SEC) seconds. Further, it is a reasonable guess
that if clock_t is signed (which you can test at runtime) and if
sizeof(clock_t) is equal to one (or more) of sizeof(short),
sizeof(int), sizeof(long), or sizeof(long long), the maximum value
of a clock_t is very likely equal to the corresponding SHRT_MAX,
INT_MAX, LONG_MAX, or LLONG_MAX. If it's unsigned you can determine
the maximum value by setting a clock_t variable to (clock_t)-1,
then assigning that to some variable with bigger range, such as
long double. Now, how much is that maximum value divided by
CLOCKS_PER_SEC in seconds? It's OK if you guess low.

Now, you might get in trouble if your program can be heavily
multi-threaded (no, I'm not talking about a thread-aware program,
I'm talking about the compiler dividing the program into threads
on its own) by a smart compiler (and is running on, for example,
a kilo-processor array) and clock_t time in seconds goes by faster
than time_t time.

Gordon L. Burditt
 
D

Dan Pop

In said:
You don't need to combine them. Check clock() and time() periodically.

What exactly "periodically" means? How do you know when it's time to
check them?
Compute the difference between the last call to clock() and this
one, and add it to a running sum in a variable with enough range
to handle the sum with reasonable precision and range (e.g. long
double, or use a bignum package). Compute the difference between
the last call to time() and this one. If it's longer than the
fastest possible wraparound time (e.g. 36 minutes above), you *MIGHT*
have blown it and your result should be considered possibly inaccurate.
If it's not, you should have reasonable accuracy.


In the above situation it doesn't get hairier, but you might
actually get an accurate answer even if you're not sure it is accurate.

Now, about computing the wraparound time: you know that difftime()
returns the difference of two times in units of seconds, and you
know that the difference of two clock_t values is in units of
(1.0/CLOCKS_PER_SEC) seconds.

Doesn't help much if the wraparound time is less than one second, does it?

Dan
 
R

Richard Heathfield

Dan said:
What exactly "periodically" means? How do you know when it's time to
check them?

You can find out when it's time to check them by checking clock() and time()
periodically.

<g,d&r>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,091
Messages
2,570,604
Members
47,224
Latest member
Gwen068088

Latest Threads

Top