如何在 Windows 上以 C++ 为单位测量 CPU 时间并包括 system() 的调用
How can I measure CPU time in C++ on windows and include calls of system()?
我想在C++算法上运行一些基准测试,并希望根据输入获得所需的CPU时间。我在Windows 7上使用Visual Studio 2012。我已经发现了一种在 Windows 中计算 CPU 时间的方法:如何在 Linux/Windows 上测量 CPU 时间和挂钟时间?
但是,我在我的算法中使用 system() 命令,它不是这样测量的。那么,如何通过 system() 测量 CPU 时间并包含脚本调用的时间?
我应该补充一个小例子。这是我的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 文件的执行。
一种可能性是在系统调用上获取句柄,这可能以某种方式吗?
Linux:
- 对于挂钟时间,请使用 gettimeofday() 或 clock_gettime()
- 对于 CPU 时间,请使用 getrusage() 或 times()
它实际上会打印程序占用的 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 thisn";
return 0;
}
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
//do your job here
return 0;
}
>如果您使用 C++11(或有权访问它),std::chrono
具有计算程序运行时间所需的所有功能。
在创建任何子流程之前,您需要将流程添加到 Job 对象。 然后,子进程将在同一作业中自动运行,所需的信息可以在JOBOBJECT_BASIC_ACCOUNTING_INFORMATION
结构的TotalUserTime
和TotalKernelTime
成员中找到,可通过 QueryInformationJobObject
函数获得。
更多信息:
- 作业的资源核算
-
JOBOBJECT_BASIC_ACCOUNTING_INFORMATION
结构
从 Windows 8 开始,支持嵌套作业,因此即使某些程序已依赖于作业对象,也可以使用此方法。
我认为没有跨平台机制。 使用 CreateProcess 启动应用程序,并使用 WaitForSingleObject 完成应用程序,将允许您获得直接后代时间。 之后,您将需要作业对象进行完整的会计核算(如果您需要为孙子孙女计时)
您也可以尝试外部采样探查器。 我在Windows下使用了免费赠品"Sleepy"[http://sleepy.sourceforge.net/]甚至更好的"Very Sleepy"[http://www.codersnotes.com/sleepy/]分析器,并且对结果非常满意 - 在几分钟内几乎没有任何努力地格式化了信息。
有一个名为"Shiny"[http://sourceforge.net/projects/shinyprofiler/]的类似项目应该可以在Windows和*nix上运行。
您可以尝试使用加速计时器。 它具有跨平台功能。 来自 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;
}
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 为什么 cmake 许可证<>样式不包括?
- 计算平均值,不包括上次得分
- 从多个源构造一个对象,包括一个对象向量
- 如何在c++中使用system()来运行包含空格的python脚本
- System.InvalidCastException - SQL to C++ - safe_cast<float>
- C++/CLI System.AccessViolation在托管类中调用非托管函数时出现异常
- 来自 Android 应用程序内部的 boost 类型的 boost::wrapexcept<boost::system::system_error> 的未捕获异常
- 在编译中包括 Botan 2
- 将值从另一个数组写入数组,不包括不需要的值 C++
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)
- 包括C++头文件
- CPP 包括 Azure DevOps 中的目录设置
- 程序在使用 system() 启动另一个可执行文件时停止
- 为什么我的 DeviceInformation 对象没有 System.Devices.InterfaceClassGuid 属性?
- 为什么"using System;"不被视为不良做法?
- C++ 合并字符串以'system'函数错误
- 包括STL,而不会乱扔全球范围
- 如何在 Windows 上以 C++ 为单位测量 CPU 时间并包括 system() 的调用