在 C++ 中获得准确的执行时间(微秒)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21856025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting an accurate execution time in C++ (micro seconds)
提问by user3323616
I want to get an accurate execution time in micro seconds of my program implemented with C++. I have tried to get the execution time with clock_t but it's not accurate.
我想以微秒为单位获得我用 C++ 实现的程序的准确执行时间。我试图用 clock_t 获得执行时间,但它不准确。
回答by OlivierLi
If you are using c++11 or later you could use std::chrono::high_resolution_clock
.
如果您使用的是 c++11 或更高版本,则可以使用std::chrono::high_resolution_clock
.
A simple use case :
一个简单的用例:
auto start = std::chrono::high_resolution_clock::now();
...
auto elapsed = std::chrono::high_resolution_clock::now() - start;
long long microseconds = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
This solution has the advantage of being portable.
该解决方案具有便携性的优点。
Beware that micro-benchmarking is hard. It's very easy to measure the wrong thing (like your benchmark optimizing away), or to include page-faults in your timed region, or fail to account for CPU frequency idle vs. turbo.
请注意,微基准测试很难。很容易衡量错误的事情(例如您的基准优化),或者在您的定时区域中包含页面错误,或者无法考虑 CPU 频率空闲与涡轮增压。
See Idiomatic way of performance evaluation?for some general tips, e.g. sanity check by testing the other one first and see if that changes which one appears faster.
请参阅绩效评估的惯用方式?对于一些一般提示,例如通过先测试另一个来检查完整性,看看是否会改变哪个看起来更快。
回答by Sunil Bojanapally
If you are looking how much time is consumed in executing your program from Unix shell, make use of Linux timeas below,
如果您正在查看从 Unix shell 执行程序所消耗的时间,请使用 Linux时间,如下所示,
time ./a.out
real 0m0.001s
user 0m0.000s
sys 0m0.000s
Secondly if you want time took in executing number of statements in the program code (C) try making use of gettimeofday()as below,
其次,如果您希望在程序代码 (C) 中执行多个语句所花费的时间,请尝试使用如下所示的gettimeofday(),
#include <sys/time.h>
struct timeval tv1, tv2;
gettimeofday(&tv1, NULL);
/* Program code to execute here */
gettimeofday(&tv2, NULL);
printf("Time taken in execution = %f seconds\n",
(double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
(double) (tv2.tv_sec - tv1.tv_sec));
回答by Gabriel Staples
Here's how to get simple C-like millisecond, microsecond, and nanosecond timestamps in C++:
以下是如何在 C++ 中获得简单的类似 C 的毫秒、微秒和纳秒时间戳:
The new C++11 std::chrono
library is one of the most complicated piles of mess I have ever seen or tried to figure out how to use, but at least it is cross-platform!
新的 C++11std::chrono
库是我见过或试图弄清楚如何使用的最复杂的一堆乱码之一,但至少它是跨平台的!
So, if you'd like to simplify it down and make it more "C-like", including removing all of the type-safe class stuff it does, here's 3 simple and very easy-to-use functions to get timestamps in milliseconds, microseconds, and nanoseconds...that only took me about 12 hrs to write*:
所以,如果你想简化它并使它更像 C 语言,包括删除它所做的所有类型安全的类的东西,这里有 3 个简单且非常易于使用的函数来获取以毫秒为单位的时间戳、微秒和纳秒……我只用了大约 12 小时来编写*:
NB: In the code below, you might consider using std::chrono::steady_clock
instead of std::chrono::high_resolution_clock
. Their definitions from here (https://en.cppreference.com/w/cpp/chrono) are as follows:
注意:在下面的代码中,您可能会考虑使用std::chrono::steady_clock
代替std::chrono::high_resolution_clock
。他们在这里的定义(https://en.cppreference.com/w/cpp/chrono)如下:
- steady_clock (C++11) - monotonic clock that will never be adjusted
- high_resolution_clock (C++11) - the clock with the shortest tick period available
- stable_clock (C++11) - 永远不会被调整的单调时钟
- high_resolution_clock (C++11) - 可用最短滴答周期的时钟
#include <chrono>
// NB: ALL OF THESE 3 FUNCTIONS BELOW USE SIGNED VALUES INTERNALLY AND WILL EVENTUALLY OVERFLOW (AFTER 200+ YEARS OR
// SO), AFTER WHICH POINT THEY WILL HAVE *SIGNED OVERFLOW*, WHICH IS UNDEFINED BEHAVIOR (IE: A BUG) FOR C/C++.
// But...that's ok...this "bug" is designed into the C++11 specification, so whatever. Your machine won't run for 200
// years anyway...
// Get time stamp in milliseconds.
uint64_t millis()
{
uint64_t ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::
now().time_since_epoch()).count();
return ms;
}
// Get time stamp in microseconds.
uint64_t micros()
{
uint64_t us = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::
now().time_since_epoch()).count();
return us;
}
// Get time stamp in nanoseconds.
uint64_t nanos()
{
uint64_t ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::
now().time_since_epoch()).count();
return ns;
}
* (Sorry, I've been more of an embedded developer than a standard computer programmer so all this high-level, abstracted static-member-within-class-within-namespace-within-namespace-within-namespace stuff confuses me. Don't worry, I'll get better.)
* (抱歉,我更像是一名嵌入式开发人员,而不是标准的计算机程序员,所以所有这些高级抽象静态成员内类内命名空间内命名空间内命名空间内的东西让我感到困惑。唐别担心,我会好起来的。)
Q: Why std::chrono
?
问:为什么std::chrono
?
A: Because C++ programmers like to go crazy with things, so they made it handle units for you. Here's a few cases of some C++ weirdness and uses of std::chrono
. Reference this page: https://en.cppreference.com/w/cpp/chrono/duration.
A:因为 C++ 程序员喜欢对事物发疯,所以他们让它为你处理单元。下面是一些 C++ 怪异之处和std::chrono
. 参考此页面:https: //en.cppreference.com/w/cpp/chrono/duration。
So you can declare a variable of 1 second and change it to microseconds with no cast like this:
因此,您可以声明一个 1 秒的变量并将其更改为微秒,而无需像这样进行强制转换:
// Create a time object of type `std::chrono::seconds` & initialize it to 1 sec
std::chrono::seconds time_sec(1);
// integer scale conversion with no precision loss: no cast
std::cout << std::chrono::microseconds(time_sec).count() << " microseconds\n";
And you can even specify time like this, which is super weird and going way overboard in my opinion. C++14 has literally overloaded the characters ms
, us
, ns
, etc. as function call operators to initialize std::chrono
objects of various types like this:
你甚至可以像这样指定时间,在我看来,这太奇怪了,而且太过分了。C++14 字面上重载了字符ms
、us
、ns
等作为函数调用运算符来初始化std::chrono
各种类型的对象,如下所示:
auto time_sec = 1s; // <== notice the 's' inside the code there to specify 's'econds!
// OR:
std::chrono::seconds time_sec = 1s;
// integer scale conversion with no precision loss: no cast
std::cout << std::chrono::microseconds(time_sec).count() << " microseconds\n";
Here's some more examples:
以下是更多示例:
std::chrono::milliseconds time_ms = 1ms;
// OR:
auto time_ms = 1ms;
std::chrono::microseconds time_us = 1us;
// OR:
auto time_us = 1us;
std::chrono::nanoseconds time_ns = 1ns;
// OR:
auto time_ns = 1ns;
Personally, I'd much ratherjust simplify the language and do this, like I already do, and as has been done in both C and C++ prior to this for decades:
就我个人而言,我更愿意简化语言并执行此操作,就像我已经做的那样,并且在此之前几十年来在 C 和 C++ 中都已完成:
// Notice the `_sec` at the end of the variable name to remind me this variable has units of *seconds*!
uint64_t time_sec = 1;
And here's a few references:
这里有一些参考:
- Clock types (https://en.cppreference.com/w/cpp/chrono):
system_clock
steady_clock
high_resolution_clock
utc_clock
tai_clock
gps_clock
file_clock
- etc.
- Getting an accurate execution time in C++ (micro seconds)(answer by @OlivierLi)
- http://en.cppreference.com/w/cpp/chrono/time_point/time_since_epoch
- http://en.cppreference.com/w/cpp/chrono/duration- shows types such as hours, minutes, seconds, milliseconds, etc
- http://en.cppreference.com/w/cpp/chrono/system_clock/now
- 时钟类型(https://en.cppreference.com/w/cpp/chrono):
system_clock
steady_clock
high_resolution_clock
utc_clock
tai_clock
gps_clock
file_clock
- 等等。
- 在 C++ 中获得准确的执行时间(微秒)(@OlivierLi 的回答)
- http://en.cppreference.com/w/cpp/chrono/time_point/time_since_epoch
- http://en.cppreference.com/w/cpp/chrono/duration- 显示小时、分钟、秒、毫秒等类型
- http://en.cppreference.com/w/cpp/chrono/system_clock/now
Video I need to watch still:
我需要继续观看的视频:
Related:
有关的:
回答by parrowdice
If you're on Windows, you can use QueryPerformanceCounter
如果您使用的是 Windows,则可以使用QueryPerformanceCounter
See How to use the QueryPerformanceCounter function to time code in Visual C++
请参见如何在 Visual C++ 中使用 QueryPerformanceCounter 函数对代码进行计时
__int64 ctr1 = 0, ctr2 = 0, freq = 0;
int acc = 0, i = 0;
// Start timing the code.
if (QueryPerformanceCounter((LARGE_INTEGER *)&ctr1)!= 0)
{
// Code segment is being timed.
for (i=0; i<100; i++) acc++;
// Finish timing the code.
QueryPerformanceCounter((LARGE_INTEGER *)&ctr2);
Console::WriteLine("Start Value: {0}",ctr1.ToString());
Console::WriteLine("End Value: {0}",ctr2.ToString());
QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
Console::WriteLine(S"QueryPerformanceCounter minimum resolution: 1/{0} Seconds.",freq.ToString());
// In Visual Studio 2005, this line should be changed to: Console::WriteLine("QueryPerformanceCounter minimum resolution: 1/{0} Seconds.",freq.ToString());
Console::WriteLine("100 Increment time: {0} seconds.",((ctr2 - ctr1) * 1.0 / freq).ToString());
}
else
{
DWORD dwError = GetLastError();
Console::WriteLine(S"Error value = {0}",dwError.ToString());// In Visual Studio 2005, this line should be changed to: Console::WriteLine("Error value = {0}",dwError.ToString());
}
// Make the console window wait.
Console::WriteLine();
Console::Write("Press ENTER to finish.");
Console::Read();
return 0;
You can put it around a call to CreateProcess(...)
and WaitForSingleObject(...)
for the entire process lifetime, otherwise around the main function for your code.
您可以将它放在对整个进程生命周期的调用CreateProcess(...)
和调用周围WaitForSingleObject(...)
,否则放在代码的 main 函数周围。