How can I measure CPU time in C++ on windows and include calls of system()?

…衆ロ難τιáo~ 提交于 2019-12-07 00:55:37

问题


I want to run some benchmarks on a C++ algorithm and want to get the CPU time it takes, depending on inputs. I use Visual Studio 2012 on Windows 7. I already discovered one way to calculate the CPU time in Windows: How can I measure CPU time and wall clock time on both Linux/Windows?

However, I use the system() command in my algorithm, which is not measured that way. So, how can I measure CPU time and include the times of my script calls via system()?

I should add a small example. This is my get_cpu_time-function (From the link described above):

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;
    }
}

That works fine so far, and when I made a program, that sorts some array (or does some other stuff that takes some time), it works fine. However, when I use the system()-command like in this case, it doesn't:

int main( int argc, const char* argv[] )
{
    double start = get_cpu_time();
    double end;
    system("Bla.exe");
    end = get_cpu_time();

    printf("Everything took %f seconds of CPU time", end - start);

    std::cin.get();

}

The execution of the given exe-file is measured in the same way and takes about 5 seconds. When I run it via system(), the whole thing takes a CPU time of 0 seconds, which obviously does not include the execution of the exe-file.

One possibility would be to get a HANDLE on the system call, is that possible somehow?


回答1:


Linux:

  • For the wall clock time, use gettimeofday() or clock_gettime()
  • For the CPU time, use getrusage() or times()



回答2:


It will actually prints the CPU time that your program takes. But if you use threads in your program, It will not work properly. You should wait for thread to finish it's job before taking the finish CPU time. So basically you should write this:

WaitForSingleObject(threadhandle, INFINITE);

If you dont know what exactly you use in your program (if it's multithreaded or not..) you can create a thread for doing that job and wait for termination of thread and measure the time.

DWORD WINAPI MyThreadFunction( LPVOID lpParam );
int main()
{
DWORD   dwThreadId;
HANDLE  hThread;

int startcputime, endcputime, wcts, wcte;

startcputime = cputime();

hThread = CreateThread( 
            NULL,                   // default security attributes
            0,                      // use default stack size  
            MyThreadFunction,       // thread function name
            NULL,                   // argument to thread function 
            0,                      // use default creation flags 
            dwThreadIdArray);

WaitForSingleObject(hThread, INFINITE);

endcputime = cputime();

std::cout << "it took " << endcputime - startcputime << " s of CPU to execute this\n";

return 0;
}

DWORD WINAPI MyThreadFunction( LPVOID lpParam ) 
{ 
    //do your job here
    return 0; 
} 



回答3:


You can try using boost timer. It is cross-platform capable. Sample code from boost web-site:

#include <boost/timer/timer.hpp>
#include <cmath>

int main() {
 boost::timer::auto_cpu_timer t;

  for (long i = 0; i < 100000000; ++i)
    std::sqrt(123.456L); // burn some time

 return 0;
}



回答4:


If your using C++11 (or have access to it) std::chrono has all of the functions you need to calculate how long a program has run.




回答5:


You'll need to add your process to a Job object before creating any child processes. Child processes will then automatically run in the same job, and the information you want can be found in the TotalUserTime and TotalKernelTime members of the JOBOBJECT_BASIC_ACCOUNTING_INFORMATION structure, available through the QueryInformationJobObject function.

Further information:

  • Resource Accounting for Jobs
  • JOBOBJECT_BASIC_ACCOUNTING_INFORMATION structure

Beginning with Windows 8, nested jobs are supported, so you can use this method even if some of the programs already rely on job objects.




回答6:


I don't think there is a cross platform mechanism. Using CreateProcess to launch the application, with a WaitForSingleObject for the application to finish, would allow you to get direct descendants times. After that you would need job objects for complete accounting (if you needed to time grandchildren)




回答7:


You might also give external sampling profilers a shot. I've used the freebie "Sleepy" [http://sleepy.sourceforge.net/]and even better "Very Sleepy" [http://www.codersnotes.com/sleepy/] profilers under Windows and been very happy with the results -- nicely formatted info in a few minutes with virtually no effort.

There is a similar project called "Shiny" [http://sourceforge.net/projects/shinyprofiler/] that is supposed to work on both Windows and *nix.



来源:https://stackoverflow.com/questions/19976901/how-can-i-measure-cpu-time-in-c-on-windows-and-include-calls-of-system

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!