Can clock() be used as a dependable API to measure time taken by CPU to execute a snippet of code? When verified usng times() / clock(), both do not seem to measure the CPU time taken precisely.
Firstly, can the APIs clock()/times() be used to measure the execution time of a function/snippet of code, as given in the example below? Is there a better and dependable alternative? The mechanism is to work on Linux, HP-UX, IBM-AIX and Sun Solaris as we need to measure (&& compare) the performance of a piece of code on all these platforms.
Kindly suggest. Also, please let me know if am missing anything trivial.
bbb@m_001:/tmp/kk1$ ./perf_clock 102400
{clock(): S 0 E 0 D 0.0000000000}
bbb@m_001:/tmp/kk1$ ./perf_clock 204800
{clock(): S 0 E 10000 D 0.0100000000}
bbb@m_001:/tmp/kk1$ cat perf_clock.c
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
void test_clock(char* sbuf, int* len){
clock_t start, end; int i=0;
start = clock();
while(i++ < 500) memset((char*)sbuf,0,*len);
end = clock();
printf("{clock(): S %10lu E %10lu D %15.10f}\n",
start,end,(end-start)/(double) CLOCKS_PER_SEC);
}
int main(int argc,char* argv[])
{
int len=atoi(argv[1]);
char *sbuf=(char*)malloc(len);
test_clock(sbuf,&len);
free(sbuf); return 0;
}
The results seem to say that to memset() a 100 KB chunk, 500 times, there is no time spent. Or does it say that it is not measurable in microseconds?
Actually, it is not memset() but another function[that prepares a huge structure sized around 1MB, mallocs a copy of this structure, does an Oracle DB select and populate these structures with the data from DB] which am trying to measure. Even this shows 0 ticks, and that is what has kept me confused.
Thanks!
On recent Linux's (*). you can get this information from the /proc filesystem. In the file /proc/PID/stat
the 14th entry has the number of jiffies used in userland code and the 15th entry has the number of jiffies used in system code.
If you want to see the data on a per-thread basis, you should reference the file /proc/PID/task/TID/stat
instead.
To convert jiffies to microseconds, you can use the following:
define USEC_PER_SEC 1000000UL
long long jiffies_to_microsecond(long long jiffies)
{
long hz = sysconf(_SC_CLK_TCK);
if (hz <= USEC_PER_SEC && !(USEC_PER_SEC % hz))
{
return (USEC_PER_SEC / hz) * jiffies;
}
else if (hz > USEC_PER_SEC && !(hz % USEC_PER_SEC))
{
return (jiffies + (hz / USEC_PER_SEC) - 1) / (hz / USEC_PER_SEC);
}
else
{
return (jiffies * USEC_PER_SEC) / hz;
}
}
If all you care about is the per-process statistics, getrusage
is easier. But if you want to be prepared to do this on a per-thread basis, this technique is better as other then the file name, the code would be identical for getting the data per-process or per-thread.
* - I'm not sure exactly when the stat file was introduced. You will need to verify your system has it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With