Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance profiler: How to use unsigned long to measure time in microseconds?

Tags:

c++

c

I am using unsigned long to collect performance data while profiling an application as follows

  1. unsigned long time_taken = (unsigned long) ((finish_time_in_nano_sec - start_time_in_nano_sec)/1000);

  2. Write time_taken to a file. Do this for every function that gets called in my app.

  3. Now after app execution, have a separate program read the above file and sum up the time taken for every function including call counts such as

func_name aggregate_time call_counts

The problem I have is that for some functions, the aggregate_time field is a 20 digit value i.e. the maximum value an unsigned long can hold. This cannot be true because I measure time in microseconds and don't run my app for more than like 20 seconds. How can it then be a 20 digit value?

Do you see mistakes in Steps 1,2 and 3?

Regards, Krishna

EDIT:

1) Time measurement: clock_gettime(CLOCK_REALTIME, &start_time); clock_gettime(CLOCK_REALTIME, &finish_time); unsigned long time_taken = (unsigned long)((finish_time.tv_nsec - art_time.tv_nsec)/1000);

2) File write: fwrite(&time_taken, sizeof(unsigned long), 1, datafile);

3) File read: fread(&time_taken, sizeof(long), 1, datafile);

like image 273
Krishna Avatar asked Dec 31 '25 01:12

Krishna


1 Answers

The problem is in your time measurement code:

clock_gettime(CLOCK_REALTIME, &start_time);
clock_gettime(CLOCK_REALTIME, &finish_time);
unsigned long time_taken = (unsigned long)((finish_time.tv_nsec - start_time.tv_nsec)/1000);

If a 1-second clock boundary is crossed between start_time and finish_time, then your subtraction could result in a negative value, and will then be converted to a very large positive unsigned value.

You need to take into account the tv_sec member of the times as well:

unsigned long time_taken;
time_taken = (unsigned long)((finish_time.tv_sec - start_time.tv_sec) * 1000000);
time_taken += (unsigned long)(finish_time.tv_nsec / 1000);
time_taken -= (unsigned long)(start_time.tv_nsec / 1000);

(eg a clock time of 23989032.452 seconds would be representated as a struct timespec with .tv_sec = 23989032 and .tv_nsec = 452000000)

like image 107
caf Avatar answered Jan 02 '26 15:01

caf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!