How can I measure CPU time and wall clock time on both Linux/Windows?

80,975

Solution 1

Here's a copy-paste solution that works on both Windows and Linux as well as C and C++.

As mentioned in the comments, there's a boost library that does this. But if you can't use boost, this should work:

//  Windows
#ifdef _WIN32
#include <Windows.h>
double get_wall_time(){
    LARGE_INTEGER time,freq;
    if (!QueryPerformanceFrequency(&freq)){
        //  Handle error
        return 0;
    }
    if (!QueryPerformanceCounter(&time)){
        //  Handle error
        return 0;
    }
    return (double)time.QuadPart / freq.QuadPart;
}
double get_cpu_time(){
    FILETIME a,b,c,d;
    if (GetProcessTimes(GetCurrentProcess(),&a,&b,&c,&d) != 0){
        //  Returns total user time.
        //  Can be tweaked to include kernel times as well.
        return
            (double)(d.dwLowDateTime |
            ((unsigned long long)d.dwHighDateTime << 32)) * 0.0000001;
    }else{
        //  Handle error
        return 0;
    }
}

//  Posix/Linux
#else
#include <time.h>
#include <sys/time.h>
double get_wall_time(){
    struct timeval time;
    if (gettimeofday(&time,NULL)){
        //  Handle error
        return 0;
    }
    return (double)time.tv_sec + (double)time.tv_usec * .000001;
}
double get_cpu_time(){
    return (double)clock() / CLOCKS_PER_SEC;
}
#endif

There's a bunch of ways to implement these clocks. But here's what the above snippet uses:

For Windows:

For Linux:


And here's a small demonstration:

#include <math.h>
#include <iostream>
using namespace std;

int main(){

    //  Start Timers
    double wall0 = get_wall_time();
    double cpu0  = get_cpu_time();

    //  Perform some computation.
    double sum = 0;
#pragma omp parallel for reduction(+ : sum)
    for (long long i = 1; i < 10000000000; i++){
        sum += log((double)i);
    }

    //  Stop timers
    double wall1 = get_wall_time();
    double cpu1  = get_cpu_time();

    cout << "Wall Time = " << wall1 - wall0 << endl;
    cout << "CPU Time  = " << cpu1  - cpu0  << endl;

    //  Prevent Code Elimination
    cout << endl;
    cout << "Sum = " << sum << endl;

}

Output (12 threads):

Wall Time = 15.7586
CPU Time  = 178.719

Sum = 2.20259e+011

Solution 2

C++11. Much easier to write!

Use std::chrono::system_clock for wall clock and std::clock for cpu clock http://en.cppreference.com/w/cpp/chrono/system_clock

#include <cstdio>
#include <ctime>
#include <chrono>

.... 

std::clock_t startcputime = std::clock();
do_some_fancy_stuff();
double cpu_duration = (std::clock() - startcputime) / (double)CLOCKS_PER_SEC;
std::cout << "Finished in " << cpu_duration << " seconds [CPU Clock] " << std::endl;


auto wcts = std::chrono::system_clock::now();
do_some_fancy_stuff();
std::chrono::duration<double> wctduration = (std::chrono::system_clock::now() - wcts);
std::cout << "Finished in " << wctduration.count() << " seconds [Wall Clock]" << std::endl;

Et voilà, easy and portable! No need for #ifdef _WIN32 or LINUX!

You could even use chrono::high_resolution_clock if you need more precision http://en.cppreference.com/w/cpp/chrono/high_resolution_clock

Solution 3

To give a concrete example of @lip's suggestion to use boost::timer if you can (tested with Boost 1.51):

#include <boost/timer/timer.hpp>

// this is wallclock AND cpu time
boost::timer::cpu_timer timer;

... run some computation ...

boost::timer::cpu_times elapsed = timer.elapsed();
std::cout << " CPU TIME: " << (elapsed.user + elapsed.system) / 1e9 << " seconds"
          << " WALLCLOCK TIME: " << elapsed.wall / 1e9 << " seconds"
          << std::endl;
Share:
80,975
yak
Author by

yak

Updated on July 21, 2022

Comments

  • yak
    yak almost 2 years

    I mean: how can I measure time my CPU spent on function execution and wall clock time it takes to run my function? (Im interested in Linux/Windows and both x86 and x86_64). See what I want to do (Im using C++ here but I would prefer C solution):

    int startcputime, endcputime, wcts, wcte;
    
    startcputime = cputime();
    function(args);
    endcputime = cputime();
    
    std::cout << "it took " << endcputime - startcputime << " s of CPU to execute this\n";
    
    wcts = wallclocktime();
    function(args);
    wcte = wallclocktime();
    
    std::cout << "it took " << wcte - wcts << " s of real time to execute this\n";
    

    Another important question: is this type of time measuring architecture independent or not?

  • yak
    yak almost 11 years
    and it gives me which time? wall clock time or cpu time?
  • syb0rg
    syb0rg almost 11 years
    It measures CPU time, not wall-clock time if that is what you are looking for.
  • Mysticial
    Mysticial almost 11 years
    @syb0rg Actually, clock() gives cpu time on Linux, and wall time on Windows.
  • yak
    yak almost 11 years
    Im looking for both;) cheers for this, so now I have to look for just a wall clock time :P
  • yak
    yak almost 11 years
    @Mysticial: are you 100% sure? can you give any code samples (for win/lin)? any docs about this issue?
  • Mysticial
    Mysticial almost 11 years
    @yak Just try it. You'll see that clock() gives real time regardless of thread activity.
  • syb0rg
    syb0rg almost 11 years
    @Mysticial I was misinformed, sorry. Leave it up to Windows to screw with things.
  • Christoph
    Christoph almost 11 years
    @syb0rg: clock() is supposed to return CPU time as per ISO standard; MS documention clearly states that it returns wall-clock time in Windows, though...
  • yak
    yak almost 11 years
    Thank you so much for this! Just two more questions: are those methods architecture-independent? Is it possible to do the same thing (get cpu and wall time) using inline asseembly (and function like, lets say, rdtsc?)
  • Mysticial
    Mysticial almost 11 years
    @yak It shouldn't be. They are OS-specific. And Windows probably uses rdtsc() to implement the performance counters. But if it were on a different architecture, it would be the OS's job to implement those functions. As far as doing these in inline assembly, it's tricky. Note that rdtsc() by itself isn't enough to get wall time since you still need something to give you how many ticks there are in a second. And I'm not aware of anything outside the OS that can give you CPU time.
  • dynamic
    dynamic over 10 years
    is the elapsed time (wall1 - wall0) in seconds ?
  • Mysticial
    Mysticial over 10 years
    @llnk Yes, they're all in seconds.
  • farindk
    farindk almost 10 years
    clock() works fine on Linux, but does not include the time spent in child processes (e.g., started by a system() call). If you need to also measure the time spent in the child processes, have a look at times(), which gives you cpu time and system time for the current process and for the child processes. Note that the clocks per second is not CLOCKS_PER_SEC here, but rather sysconf(_SC_CLK_TCK).
  • Tyler Streeter
    Tyler Streeter over 9 years
    Be careful with QueryPerformanceCounter because it can leap forward unexpectedly by several seconds, so you have to compare it constantly with GetTickCount: Microsoft KB274323.
  • NoseKnowsAll
    NoseKnowsAll almost 9 years
    Great answer. However, for your Linux/Posix versions, you have to #include <ctime> or <time.h> as well in order to use the clock() function and CLOCKS_PER_SEC.
  • Tomáš Zato
    Tomáš Zato over 8 years
    Which one is the total time?
  • Andre Holzner
    Andre Holzner over 8 years
    'total' in which sense ? CPU time is usually summed over all threads/cores (sum of how long each CPU core was busy executing the code), wallclock time is how long you had to wait until the code completes. For code running on more than one CPU core, CPU time can be larger than the wallclock time.
  • Neel Basu
    Neel Basu almost 8 years
    No you didn't figure out both are 'total' one is wall clock time and another one is cpu time.
  • huseyin tugrul buyukisik
    huseyin tugrul buyukisik about 6 years
    Exact same code on my windows machine (64-bit) running a cuda code: Wall Time = 0.251269 CPU Time = 0.0625 why the opposite? I expected CPU time to be bigger. There are some child threads spawned too. If I run nvidia visual profiler, then CPU time becomes zero while wall stays same.
  • Mysticial
    Mysticial about 6 years
    @huseyintugrulbuyukisik I don't know much about CUDA. But if it's CPU, then it sounds like the process is getting blocked or tasked out.
  • puk
    puk about 6 years
    why do you use auto on for wcts then std::chrono::duration<double> for wctduration?
  • n. m.
    n. m. almost 6 years
    Unfortunately std::clock work on Windows in a non-standard way, so "portable" is a bit too optimistic.
  • user561749
    user561749 over 3 years
    @n.'pronouns'm. In which way does std::clock work on Windows in a non-standard way? Can you explain the issue in more detail?
  • n. m.
    n. m. over 3 years
    @user561749 It measures wall clock time instead of the CPU time as required by the standard. This was discussed in other comments, read them.