如何在Windows上测量C ++中的CPU时间并包含system()的调用?

时间:2013-11-14 11:49:57

标签: c++ windows cpu-time

我想在C ++算法上运行一些基准测试,并希望获得所需的CPU时间,具体取决于输入。我在Windows 7上使用Visual Studio 2012.我已经发现了一种在Windows中计算CPU时间的方法:How can I measure CPU time and wall clock time on both Linux/Windows?

但是,我在我的算法中使用system()命令,这不是以这种方式测量的。那么,我如何测量CPU时间并通过system()包含脚本调用的次数?

我应该添加一个小例子。这是我的get_cpu_time函数(来自上面描述的链接):

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

到目前为止工作正常,当我制作一个程序时,对一些数组进行排序(或者做一些需要一些时间的其他事情),它运行正常。但是,当我在这种情况下使用system() - 命令时,它不会:

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();

}

给定exe文件的执行以相同的方式测量,大约需要5秒。当我通过system()运行它时,整个过程需要0秒的CPU时间,这显然不包括执行exe文件。

一种可能性就是在系统调用上获得一个HANDLE,这可能是某种方式吗?

7 个答案:

答案 0 :(得分:0)

Linux的:

答案 1 :(得分:0)

它实际上会打印程序占用的CPU时间。但是如果你在程序中使用线程,它将无法正常工作。在完成CPU时间之前,您应该等待线程完成它的工作。所以基本上你应该这样写:

WaitForSingleObject(threadhandle, INFINITE);

如果你不知道你在程序中使用了什么(如果它是多线程的......)你可以创建一个线程来完成这项工作并等待线程终止并测量时间。

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

答案 2 :(得分:0)

您可以尝试使用增强计时器。它具有跨平台能力。 boost网站的示例代码:

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

答案 3 :(得分:0)

如果您使用C ++ 11(或有权访问它)std::chrono具有计算程序运行时间所需的所有函数。

答案 4 :(得分:0)

在创建任何子进程之前,您需要将您的进程添加到Job对象。然后子进程将自动在同一作业中运行,您可以在TotalUserTime结构的TotalKernelTimeJOBOBJECT_BASIC_ACCOUNTING_INFORMATION成员中找到所需信息,这些成员可通过QueryInformationJobObject获得功能

更多信息:

从Windows 8 nested jobs are supported开始,即使某些程序已经依赖于作业对象,也可以使用此方法。

答案 5 :(得分:0)

我认为没有跨平台机制。使用CreateProcess启动应用程序,使用WaitForSingleObject完成应用程序,将允许您获得直接后代时间。之后,您需要完成会计的工作对象(如果您需要为孙子女计时)

答案 6 :(得分:0)

您也可以为外部采样分析器提供一个镜头。我在Windows下使用免费赠品“Sleepy”[http://sleepy.sourceforge.net/]and甚至更好的“非常困”[http://www.codersnotes.com/sleepy/]个人资料,对结果非常满意 - 几分钟内格式化的信息几乎没有任何努力

有一个名为“Shiny”[http://sourceforge.net/projects/shinyprofiler/]的类似项目应该适用于Windows和* nix。