How can I measure CPU time and wall clock time on both Linux/Windows?
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:
- Wall Time: Performance Counters
- CPU Time:
GetProcessTimes()
For Linux:
- Wall Time:
gettimeofday()
- CPU Time:
clock()
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;
yak
Updated on July 21, 2022Comments
-
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 almost 11 yearsand it gives me which time? wall clock time or cpu time?
-
syb0rg almost 11 yearsIt measures CPU time, not wall-clock time if that is what you are looking for.
-
Mysticial almost 11 years@syb0rg Actually,
clock()
gives cpu time on Linux, and wall time on Windows. -
yak almost 11 yearsIm looking for both;) cheers for this, so now I have to look for just a wall clock time :P
-
yak almost 11 years@Mysticial: are you 100% sure? can you give any code samples (for win/lin)? any docs about this issue?
-
Mysticial almost 11 years@yak Just try it. You'll see that
clock()
gives real time regardless of thread activity. -
syb0rg almost 11 years@Mysticial I was misinformed, sorry. Leave it up to Windows to screw with things.
-
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 almost 11 yearsThank 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 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 thatrdtsc()
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 over 10 yearsis the elapsed time (wall1 - wall0) in seconds ?
-
Mysticial over 10 years@llnk Yes, they're all in seconds.
-
farindk almost 10 years
clock()
works fine on Linux, but does not include the time spent in child processes (e.g., started by asystem()
call). If you need to also measure the time spent in the child processes, have a look attimes()
, which gives you cpu time and system time for the current process and for the child processes. Note that the clocks per second is notCLOCKS_PER_SEC
here, but rathersysconf(_SC_CLK_TCK)
. -
Tyler Streeter over 9 yearsBe careful with QueryPerformanceCounter because it can leap forward unexpectedly by several seconds, so you have to compare it constantly with GetTickCount: Microsoft KB274323.
-
NoseKnowsAll almost 9 yearsGreat answer. However, for your Linux/Posix versions, you have to
#include <ctime>
or<time.h>
as well in order to use theclock()
function andCLOCKS_PER_SEC
. -
Tomáš Zato over 8 yearsWhich one is the total time?
-
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 almost 8 yearsNo you didn't figure out both are 'total' one is wall clock time and another one is cpu time.
-
huseyin tugrul buyukisik about 6 yearsExact 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 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 about 6 yearswhy do you use
auto
on forwcts
thenstd::chrono::duration<double>
forwctduration
? -
n. m. almost 6 yearsUnfortunately
std::clock
work on Windows in a non-standard way, so "portable" is a bit too optimistic. -
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. 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.