36

I am running a .cpp code (i) in sequential style and (ii) using OpenMP statements. I am trying to see the time difference. For calculating time, I use this:

#include <time.h>
.....
main()
{

  clock_t start, finish;
  start = clock();
  .
  .
  .
  finish = clock();

  processing time = (double(finish-start)/CLOCKS_PER_SEC);

 }

The time is pretty accurate in sequential (above) run of the code. It takes about 8 seconds to run this. When I insert OpenMP statements in the code and thereafter calculate the time I get a reduction in time, but the time displayed is about 8-9 seconds on the console, when actually its just 3-4 seconds in real time!

Here is how my code looks abstractly:

#include <time.h>
.....
main()
{

  clock_t start, finish;
  start = clock();
  .
  .
  #pragma omp parallel for
  for( ... )
     for( ... )
       for (...)
    {           
      ...;      
    }
  .
  .
  finish = clock();

  processing time = (double(finish-start)/CLOCKS_PER_SEC);

 }

When I run the above code, I get the reduction in time but the time displayed is not accurate in terms of real time. It seems to me as though the clock () function is calculating each thread's individual time and adding up them up and displaying them.

Can someone tell the reason for this or suggest me any other timing function to use to measure the time in OpenMP programs?

Thanks.

Puppy
  • 144,682
  • 38
  • 256
  • 465
Benny
  • 5,218
  • 5
  • 24
  • 28
  • Mind setting this answer: https://stackoverflow.com/a/63621357/3785618 being the correct answer? It's 8 years later, and technically is the most appropriate one, so it confuses when people see this one (https://stackoverflow.com/a/10874375/3785618) as checked. – Maksim I. Kuzmin Mar 23 '21 at 17:10

5 Answers5

52

It seems to me as though the clock () function is calculating each thread's individual time and adding up them up and displaying them.

This is exactly what clock() does - it measures the CPU time used by the process, which at least on Linux and Mac OS X means the cumulative CPU time of all threads that have ever existed in the process since it was started.

Real-clock (a.k.a. wall-clock) timing of OpenMP applications should be done using the high resolution OpenMP timer call omp_get_wtime() which returns a double value of the number of seconds since an arbitrary point in the past. It is a portable function, e.g. exists in both Unix and Windows OpenMP run-times, unlike gettimeofday() which is Unix-only.

Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
  • "all threads in the process"... may or may not be the case. According to the documentation, reaped child processes may be included also. – Ben Voigt Jun 03 '12 at 22:26
  • Hmm, neither ISO/IEC 9899:1999 nor SUSv3 mention child processes: "The clock() function shall return the implementation's best approximation to the processor time used by the process since the beginning of an implementation-defined era related only to the process invocation." – Hristo Iliev Jun 03 '12 at 22:40
  • Well, the Linux man page says it's a point of incompatibility with some other OSes (it doesn't say which ones actually include child processes). – Ben Voigt Jun 04 '12 at 00:39
21

I've seen clock() reporting CPU time, instead of real time.

You could use

struct timeval start, end;
gettimeofday(&start, NULL);

// benchmark code

gettimeofday(&end, NULL);

delta = ((end.tv_sec  - start.tv_sec) * 1000000u + 
         end.tv_usec - start.tv_usec) / 1.e6;

To time things instead

sehe
  • 374,641
  • 47
  • 450
  • 633
  • 6
    I would hope you've seen that, it's part of the specified behavior. Please also note that `(end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec` is far less likely to overflow. – Ben Voigt Jun 03 '12 at 22:23
  • 1
    @BenVoigt I'm humbled by my splendid display of fallibility. I CW-ed this since I deserve no more credit for this answer than I already got. Thanks for correcting the (subtle/nonsubtle) errors. – sehe Jun 04 '12 at 12:27
  • what header file contains this `gettimeofday()` function? All i have is a `mingw_gettimeofday()` in `time.h`(mingw in windows 64) – samad montazeri Jun 17 '16 at 19:26
  • 1
    @samadmontazeri Google's [first result](http://linux.die.net/man/2/gettimeofday) tells me `#include ` – sehe Jun 17 '16 at 20:02
  • 1
    Why not `delta = (end.tv_sec-start.tv_sec)+(end.tv_usec-start.tv_usec)*1e-6`? Can it happen that `(end.tv_sec-start.tv_sec)*1000000u` exceeds the maximum `unsigned int` if I waited for a couple of hours? – Zhuoran He Sep 09 '16 at 17:37
  • `omp_get_wtime` should be the default choice to measure wall clock execution time in the OpenMP context. – Zulan Apr 10 '19 at 12:39
  • Thanks @Zulan specifications keep improving :) That was added in 4.5 (~2015) – sehe Apr 10 '19 at 12:49
  • Actually `omp_get_wtime` was added as part of OpenMP 2.0 (2002) – Zulan Apr 10 '19 at 13:10
  • @Zulan Ah, I misread the version reference - apparently it just lists the last-change date – sehe Apr 10 '19 at 14:32
19

You could use the built in omp_get_wtime function in omp library itself. Following is an example code snippet to find out execution time.

#include <stdio.h>
#include <omp.h>

int main(){

    double itime, ftime, exec_time;
    itime = omp_get_wtime();

    // Required code for which execution time needs to be computed
    
    ftime = omp_get_wtime();
    exec_time = ftime - itime;
    printf("\n\nTime taken is %f", exec_time);

}
Hemanth Kollipara
  • 902
  • 11
  • 16
6

Well yes, that's what clock() is supposed to do, tell you how much processor time the program used.

If you want to find elapsed real time, instead of CPU time, use a function that returns wall clock time, such as gettimeofday().

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
2
#include "ctime"

std::time_t start, end;
long delta = 0;
start = std::time(NULL);

// do your code here

end = std::time(NULL);
delta = end - start;

// output delta
Erdinc Ay
  • 3,224
  • 4
  • 27
  • 42