convert time in timespec

Hi

I have a time stored in time1:

timespec time1;

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);


// convert time to microseconds

timeInMicroseconds = (time1.tv_sec)*1e6 + (time1.tv_nsec)*1e-3;

Is this conversion correct ?

Many thanks...
that is certainly seconds and nanoseconds to micros, yes.
if it seems wrong, check the input units and that you don't have an integer or anything in there.

todays machines can run a LOT in a microsec. If you get all zeros, try a sleep for a specific time and see if you get the right answer.
Last edited on
Thanks jonnin. I did not get zero. It gives me a value.

But timespec contains:

std::time_t tv_sec

and

long tv_nsec


I have no problem with tv_nsec since it is a long number, so (time1.tv_nsec)*1e-3; would be correct.

But, I am confused with tv_sec :

tv_sec is of type time_t, so is it correct to write (time1.tv_sec)*1e6 ?

time_t is in seconds, but it represents a *date* really, not an elapsed time.
have you looked at <chrono>? What exactly are you trying to do?
Last edited on
tv_sec is of type time_t, so is it correct to write (time1.tv_sec)*1e6 ?
Yes, it is correct. See:

https://en.cppreference.com/w/c/chrono/timespec

The type time_t represents a numeric value which is usually a kind of date but doesn't need to. See:

https://en.cppreference.com/w/c/chrono/time_t

Consider using time_point instead timespec. See:

http://www.cplusplus.com/reference/chrono/time_point/
what is the point of timespec?
a 64 bit int holds about 600 billion years worth of seconds, or 6 billion years worth of ms. If we continue to use 1970, you could certainly turn that into pico's or something and still have all we need until well past the future where 256 bit integers are the norm.
I seem to have overlooked the type, and looking now, I see no use for it at all.
Thanks all for you help.

I am trying to measure the running time of a function

timespec time1, time2, time3;

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
callFunction();
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time3);

time1=diff(time2,time3);

// convert time to microseconds

timeInMicroseconds = (time1.tv_sec)*1e6 + (time1.tv_nsec)*1e-3;


I have seen another code which considered only the nano seconds part, so I get confused should I consider both in measuring the running time or only the nano seconds part?

it depends on how long it runs. Does your program run for more than a second?
To put it in perspective, you can sort over a billion numbers** in a second on a reasonably up to date PC.

here is what I use for most functions. you can get a duration instead of just a difference, but the difference is good enough for me usually (my goal usually is to reduce the value, the units don't matter).

auto start = high_resolution_clock::now();
code to time();
auto end = high_resolution_clock::now();
cout << (end - start).count()<< "\n";

the duration looks like this (whatever units -- it supports a lot)
chrono::duration_cast<chrono::seconds>(end - start).count()

**(multi threaded). ST is more like 10M in a second
Last edited on
It depends, for some input, it takes less than second, but form some it takes more.

But, time1.tv_sec, is it considered the seconds elapsed since 1970? or is it the actual seconds?

If it is the seconds elapsed since 1970, could I omit sec form running time calculation?
Last edited on
It's not correct because it's the wrong type. 1e6 and 1e-3 are doubles.

Regarding timing something, I suggest holding the start/stop values, find the difference, then convert to microsec. If you're using integral types (variants of int), the order won't matter, but using doubles will.

If you want to find the difference between two timespec values, why not code it?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct timespec operator-(const struct timespec& a, const struct timespec& b) {
    constexpr long max_msec = 1000;
    constexpr long max_usec = 1000*max_msec;
    constexpr long max_nsec = 1000*max_usec;

    struct timespec result;
    result.tv_sec = a.tv_sec - b.tv_sec;
    result.tv_nsev = a.tv_nsec - b.tv_nsec;

    if (result.tv_nsec < 0) { // carry
        --result.tv_sec;
        result.tv_nsec += max_nsec;
    }
    return result;
}


also
1
2
3
long to_usec(const struct timespec& ts) {
    return 1000*1000*ts.tv_sec + ts.tv_nsec/1000;
}


But if you're doing timings, try to move to std::chrono (as @jonnin suggested), there's loads of useful stuff there.
Last edited on
it depends.
lets break it down..
say you have a function that takes about 10 seconds.
you can print that it took 10.123456 seconds.
you can print that it took 10123.456 ms.
whatever you want to see on the screen, in other words.
I don't know how the weird time thing you have works -- but if it is split into seconds and subseconds as two fields, then you need the seconds field. Again, I would do away with all that and just use high res clock as I showed you, and then cast it to the output you want and call it a day. I don't know if its from 1970 or not but if you subtract two of them in a difference, it does not matter... all that is cleared out and you just get a few seconds and subseconds left. The extra 40something years part 'cancels out'.
Last edited on
I run my c++ in Linux,so I use clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); not chrono.

Many thanks all for suggestions and explanation

jonnin please could you correct me if I am wrong about what I understand:

timespec object contains: std::time_t tv_sec and long tv_nsec

The ref here: https://en.cppreference.com/w/cpp/chrono/c/timespec

says "Structure holding an interval broken down into seconds and nanoseconds."

Does that mean I can use either the seconds interval OR nanoseconds interval?

or it means the interval is seconds+nanoseconds ?

Last edited on
my understanding is that it is seconds+nanos, because it says "broken down into" and not "your choice of" or something like that. Its probably faster to play with it than unravel the documentation and examples. Just throw a little program with a sleep in it and see what you get when you sleep for 5 seconds.

linux has nothing to do with which function you choose to use here. Everything we talked about is standard c++ as far as I saw, its just choices.
Last edited on
This is a test code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>    
#include <time.h>

#include <unistd.h>
#include <chrono> 
using namespace std;
using namespace std::chrono; 
 

/*******************************************************************************/
//Function Name: clock_gettime and diff
//Inputs: 
//Output: 
//Description: these two functions are responsible to calculate the excution time 
/*********************************************************************************/
int clock_gettime(clockid_t clk_id, struct timespec *tp);

timespec diff(timespec start, timespec end)
  {
    timespec temp;
	  if ((end.tv_nsec-start.tv_nsec)<0) {
		  temp.tv_sec = end.tv_sec-start.tv_sec-1;
		  temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
	  } else {
		  temp.tv_sec = end.tv_sec-start.tv_sec;
		  temp.tv_nsec = end.tv_nsec-start.tv_nsec;
	  }
	  return temp;
  }
  
int main () {
	timespec time1, time2, time3;
        clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
	sleep(5);// sleep for 5 seconds
	clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time3);
	time1=diff(time2,time3);
	cout<< "seconds part is "<< time1.tv_sec <<endl;
	cout<< "nano-seconds part is "<<time1.tv_nsec <<endl;
	cout<< "converting total to micro-seconds"<<endl;
	// convert time to microseconds
	cout << (time1.tv_sec)*1e6 + (time1.tv_nsec)*1e-3<< endl;
 return 0;
}

The output is:
seconds part is 0
nano-seconds part is 36339
converting total to micro-seconds
36.339


As seen:
I sleep for 5 seconds, but the second part is 0
36 microseconds is not much like 5 seconds :)
I would dig into it until you get something that approximates 5000.
did it seem to sleep for the 5 seconds you asked for?

I hate to keep saying this, but you are fighting yourself over something that should be a couple of lines of code, and for no reason I can see....
1
2
3
4
5
6
7
8
9
10
11
int main()
{	
	auto start = high_resolution_clock::now();
	std::this_thread::sleep_for (std::chrono::seconds(5));
	auto end = high_resolution_clock::now();
	cout << chrono::duration_cast<chrono::microseconds>(end - start).count();
	return 0;
}

output (varies per run a little)
5014873
Last edited on
I sleep for 5 seconds, but the second part is 0

When you tell the computer to sleep for 5 seconds, the processor spends those 5 seconds executing a different thread, probably in a different process.

By passing CLOCK_PROCESS_CPUTIME_ID you've asked for the time that the CPU has spent executing this particular process.

Read the manual:
https://linux.die.net/man/3/clock_gettime
Last edited on
Topic archived. No new replies allowed.