8

Is there any way in C++ to calculate how long does it take to run a given program or routine in CPU time?

I work with Visual Studio 2008 running on Windows 7.

5
  • If you are on a POSIX system, look no further than getrusage. Commented Sep 26, 2012 at 16:00
  • 2
    That is a platform-dependent, non-conceptual question, thus it belongs on SO, not here. Commented Sep 26, 2012 at 16:01
  • I work with Visual Studio 2008 running on Windows 7. I've edited my question. Thank you for moving it to the right forum. :) Commented Sep 26, 2012 at 16:16
  • @pyCthon, I think I was confused. I thought there was some kind of problem in Visual C++ on Windows 7 so that time.h functions were not providing any way to measure CPU time but only elapsed real time. Commented Sep 26, 2012 at 16:51
  • I mean, would this example meet my needs?? Looking forward to your feedback. Commented Sep 26, 2012 at 17:08

5 Answers 5

8

If you want to know the total amount of CPU time used by a process, neither clock nor rdtsc (either directly or via a compiler intrinsic) is really the best choice, at least IMO. If you need the code to be portable, about the best you can do is use clock, test with the system as quiescent as possible, and hope for the best (but if you do, be aware that the resolution of clock is CLOCKS_PER_SEC, which may or may not be 1000, and even if it is, your actual timing resolution often won't be that good -- it may give you times in milliseconds, but at least normally advance tens of milliseconds at a time).

Since, however, you don't seem to mind the code being specific to Windows, you can do quite a bit better. At least if my understanding of what you're looking for is correctly, what you really want is probably GetProcessTimes, which will (separately) tell you both kernel-mode and user-mode CPU usage of the process (as well as the start time and exit time, from which you can compute wall time used, if you care). There's also QueryProcessCycleTime, which will tell you the total number of CPU clock cycles used by the process (total of both user and kernel mode in all threads). Personally, I have a hard time imagining much use for the latter though -- counting individual clock cycles can be useful for small sections of code subject to intensive optimization, but I'm less certain about how you'd apply it to a complete process. GetProcessTimes uses FILETIME structures, which support resolutions of 100 nanoseconds, but in reality most times you'll see will be multiples of the scheduler's time slice (which varies with the version of windows, but is on the order of milliseconds to tens of milliseconds).

In any case, if you truly want time from beginning to end, GetProcessTimes will let you do that -- if you spawn the program (e.g., with CreateProcess), you'll get a handle to the process which will be signaled when the child process exits. You can then call GetProcessTimes on that handle, and retrieve the times even though the child has already exited -- the handle will remain valid as long as at least one handle to the process remains open.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, @Jerry. @Doc pointed out that clock() doesn't give CPU time but wall-clock time when used in Windows environments. It doesn't happen to be the same with GetProcessTimes, does it? I mean, I guess that it works OK on Windows because the documentation you reference is about Windows. By the way, which library should I add in order to make it work?
@Vicent: Pretty much like any Windows program -- you #include <windows.h> and link with kernel32.lib -- but essentially all Windows programs link with kernel32.lib, so you probably don't need to do anything to get that.
4

Here's one way. It measures routine exeution time in milliseconds.

clock_t begin=clock(); starts before the route is executed and clock_t end=clock(); starts right after the routine exits.

The two time sets are then subtracted from each other and the result is a millisecod value.

#include <stdio.h>
#include <iostream>
#include <time.h>
using namespace std;

double get_CPU_time_usage(clock_t clock1,clock_t clock2)
{
    double diffticks=clock1-clock2;
    double diffms=(diffticks*1000)/CLOCKS_PER_SEC;
    return diffms;
} 

void test_CPU_usage()
{
  cout << "Standby.. measuring exeution time:  ";

  for (int i=0; i<10000;i++)
  {
        cout << "\b\\" << std::flush;
        cout << "\b|" << std::flush;
        cout << "\b/" << std::flush;
        cout << "\b-" << std::flush;
  }

  cout << " \n\n";
}

int main (void)
{

    clock_t begin=clock();

    test_CPU_usage();

    clock_t end=clock();

    cout << "Time elapsed: " << double(get_CPU_time_usage(end,begin)) << " ms ("<<double(get_CPU_time_usage(end,begin))/1000<<" sec) \n\n";
    return 0;
}

8 Comments

I think again this measures execution time, not CPU time?
OK, thank you. I think this other example is similar... I was confused and I thought that there was a problem with computing CPU time in Visual C++ on Windows. Sorry, and thank you again!!! :)
@AK4749, why do you think that?
James' answer at least measures true CPU time, even though as he mentions you should be careful using such a function's results
@Vicent: AFAIK clock measures CPU time under Unix or Linux, but wall clock time under Windows (see here msdn.microsoft.com/en-us/library/4e2ess30%28v=vs.110%29.aspx)
|
4

The clock() function [as provided by Visual C++ 2008] doesn't return processor time used by the program, while it should (according to the C standard and/or C++ standard). That said, to measure CPU time on Windows, I have this helper class (which is inevitably non-portable):

class ProcessorTimer
{
  public:
    ProcessorTimer() { start(); }
    void start() { ::GetProcessTimes(::GetCurrentProcess(), &ft_[3], &ft_[2], &ft_[1], &ft_[0]); }
    std::tuple<double, double> stop()
    {
        ::GetProcessTimes(::GetCurrentProcess(), &ft_[5], &ft_[4], &ft_[3], &ft_[2]);
        ULARGE_INTEGER u[4];
        for (size_t i = 0; i < 4; ++i)
        {
            u[i].LowPart = ft_[i].dwLowDateTime;
            u[i].HighPart = ft_[i].dwHighDateTime;
        }
        double user = (u[2].QuadPart - u[0].QuadPart) / 10000000.0;
        double kernel = (u[3].QuadPart - u[1].QuadPart) / 10000000.0;
        return std::make_tuple(user, kernel);
    }
  private:
    FILETIME ft_[6];
};


class ScopedProcessorTimer
{
  public:
    ScopedProcessorTimer(std::ostream& os = std::cerr) : timer_(ProcessorTimer()), os_(os) { }
    ~ScopedProcessorTimer()
    {
        std::tuple<double, double> t = timer_.stop();
        os_ << "user " << std::get<0>(t) << "\n";
        os_ << "kernel " << std::get<1>(t) << "\n";
    }
  private:
    ProcessorTimer timer_;
    std::ostream& os_;
}

For example, one can measure how long it takes a block to execute, by defining a ScopedProcessorTimer at the beginning of that {} block.

1 Comment

It seems have some different opinions, stackoverflow.com/questions/39549164/…
2

The __rdtscp intrinsic will give you the time in CPU cycles with some caveats. Here's the MSDN article

It depends really what you want to measure. For better results take the average of a few million (if not billion) iterations.

4 Comments

Thank you, @James. What do you think about the solution proposed by @Clark, using clock() function??
@Vicent It depends what you want to measure
I want to measure the time that has been really used by program when being executed, from the beginning to the end. As far as I know, it is usually called CPU time. Are there any related concepts, subtle details... that should be taken into account?
@Vicent In that case rdtscp probably too high-resolution for you. Use the clock method
0

This Code is Process Cpu Usage

ULONGLONG LastCycleTime = NULL;
LARGE_INTEGER LastPCounter;
LastPCounter.QuadPart = 0; // LARGE_INTEGER Init

                           // cpu get core number
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
int numProcessors = sysInfo.dwNumberOfProcessors;

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Process::pid);

if (hProcess == NULL)
    nResult = 0;

int count = 0;
while (true)
{
    ULONG64 CycleTime;
    LARGE_INTEGER qpcLastInt;

    if (!QueryProcessCycleTime(hProcess, &CycleTime))
        nResult = 0;

    ULONG64 cycle = CycleTime - LastCycleTime;

    if (!QueryPerformanceCounter(&qpcLastInt))
        nResult = 0;

    double Usage = cycle / ((double)(qpcLastInt.QuadPart - LastPCounter.QuadPart));

    // Scaling
    Usage *= 1.0 / numProcessors;
    Usage *= 0.1;

    LastPCounter = qpcLastInt;
    LastCycleTime = CycleTime;

    if (count > 3)
    {
        printf("%.1f", Usage);
        break;
    }

    Sleep(1); // QueryPerformanceCounter Function Resolution is 1 microsecond

    count++;
}

CloseHandle(hProcess);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.