7

我想在 C++ 算法上运行一些基准测试,并希望根据输入获得所需的 CPU 时间。我在 Windows 7 上使用 Visual Studio 2012。我已经发现了一种在 Windows 中计算 CPU 时间的方法:如何在 Linux/Windows 上测量 CPU 时间和挂钟时间?

但是,我在我的算法中使用了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,这可能吗?

4

7 回答 7

0

Linux:

于 2013-11-14T11:56:42.743 回答
0

在创建任何子进程之前,您需要将进程添加到 Job 对象。然后子进程将自动在同一个作业中运行,并且您想要的信息可以在结构的TotalUserTimeTotalKernelTime成员中找到JOBOBJECT_BASIC_ACCOUNTING_INFORMATION,可通过该QueryInformationJobObject函数获得。

更多信息:

从 Windows 8 开始,支持嵌套作业,因此即使某些程序已经依赖作业对象,您也可以使用此方法。

于 2015-04-28T18:43:28.307 回答
0

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

于 2015-02-04T02:34:46.103 回答
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; 
} 
于 2013-11-14T12:04:18.327 回答
0

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

于 2015-07-26T09:00:46.970 回答
0

您也可以试一试外部采样分析器。我在 Windows 下使用了免费赠品“Sleepy” [ http://sleepy.sourceforge.net/ ]甚至更好的“非常困” [ http://www.codersnotes.com/sleepy/]分析器,并且非常满意结果 - 在几分钟内几乎不费吹灰之力就可以很好地格式化信息。

有一个类似的项目叫做“Shiny”[ http://sourceforge.net/projects/shinyprofiler/],它应该可以在 Windows 和 *nix 上运行。

于 2015-10-08T06:19:01.140 回答
-1

您可以尝试使用增强计时器。它具有跨平台能力。来自 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;
}
于 2013-11-24T07:30:00.033 回答