When using the following example code, the tv_nsec value, I presume is looping round because it’s only an long;
#include <iostream>
using namespace std;
#include <time.h>
int main(int argc, char *argv[]) {
timespec time1, time2;
timespec timens = {0};
timens.tv_sec = 1;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
nanosleep(&timens, (struct timespec *)NULL);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
cout << time1.tv_nsec << " : " << time2.tv_nsec << endl;
cout << (time2.tv_nsec-time1.tv_nsec) << endl;
return 0;
}
$ ./microtime
2754095 : 2766801
12706
The difference between the start and end time is 12706ns (12.7us), it didn’t take 12us to sleep for 1 second, I’m reasonably sure of that! So what has happened here, has tv_nsec looped round? Assuming it’s an singed long to give a smaller range of positive values (0 to 2147483647) instead of an unsigned long (0 to 4294967295), 2147483647 nanoseconds is still just over 2 full seconds!
If I change the code to the following I get a seemingly invalid output still;
timens.tv_sec = 0;
timens.tv_nsec = 100000;
$ ./microtime
2743552 : 2754327
10775
The sleep duration was set for 100,000ns but according to that output the program has slept for 10,000ns. I know that is a small amount of time but I’m trying to show here that whether it is a long time like 1 second or a short time like 100us, there seems to be no accuracy here, or anywhere in between these values. Am I doing something wrong, have I implemented this incorrectly somehow? Why can’t I get the actual duration of the event in between the calls to clock_gettime()?
Many thanks for your time.
Update
@Oli;
I can test your suggestion with the following code but it doesn’t seem to work:
int main(int argc, char *argv[]) {
timespec time1, time2;
timespec timens = {0};
timens.tv_sec = 1;
timens.tv_nsec = 0;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
nanosleep(&timens, (struct timespec *)NULL);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
cout <<time1.tv_sec<<"s:"<<time1.tv_nsec<<"ns : "<<
time2.tv_sec<<"s:"<<time2.tv_nsec<<"ns"<<endl;
cout <<(time2.tv_nsec-time1.tv_nsec)<<endl;
return 0;
}
$ ./microtime
0s:2801478ns : 0s:2813732ns
12254
You also need to take the
tv_secfield into account when calculating the time interval.UPDATE
Also,
CLOCK_PROCESS_CPUTIME_IDmeasures CPU time used for this process. If you yield with ananosleep, this timer won’t increment. Try e.g.CLOCK_MONOTONICinstead.