rap*_*yen 5 c++ windows time c++11 c++-chrono
我试图用来chrono::steady_clock衡量程序中代码块之间经过的小数秒.我在LiveWorkSpace(http://liveworkspace.org/code/YT1I$9)中使用了这段代码:
#include <chrono>
#include <iostream>
#include <vector>
int main()
{
auto start = std::chrono::steady_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = std::chrono::steady_clock::now();
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
std::cout << "seconds since start: " << ((double)difference / 1000000);
}
Run Code Online (Sandbox Code Playgroud)
当我在我的程序中实现相同的想法时:
auto start = std::chrono::steady_clock::now();
// block of code to time
auto end = std::chrono::stead_clock::now();
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
std::cout << "seconds since start: " << ((double) difference / 1000000);
Run Code Online (Sandbox Code Playgroud)
该程序将只打印0和的值0.001.我非常怀疑我的代码块的执行时间总是等于0或1000微秒,那么这个舍入的原因是什么,以及如何消除它以便我可以获得正确的小数值?
这是一个Windows程序.
这个问题已经有了一个很好的答案.但我想补充一点建议:
在<chrono>框架内工作.建立自己的时钟.建立自己的time_point.建立自己的持续时间.该<chrono>框架非常可定制.通过在该系统中工作,您不仅可以学习std::chrono,而且当您的供应商开始提供您满意的时钟时,将您的代码从手动滚动的时间转换为std::high_resolution_clock(或其他)将是微不足道的.
首先,对您原始代码的一点点批评:
std::cout << "seconds since start: " << ((double) difference / 1000000);
Run Code Online (Sandbox Code Playgroud)
每当你看到自己引入转换常量(如1000000)来获得你想要的东西时,你就没有chrono正确使用它.你的代码不正确,只是脆弱.你确定你在那个常数中得到了正确数量的零吗?!
即使在这个简单的例子中,你应该对自己说:
我希望以双精度表示的秒数来看输出.
然后你应该chrono为你做这件事.一旦你学会了如何,这很容易:
typedef std::chrono::duration<double> sec;
sec difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
Run Code Online (Sandbox Code Playgroud)
第一行创建一个周期为1秒的类型,由double表示.
第二行只是减去你的time_points并将其分配给你的自定义持续时间类型.从单位steady_clock::time_point到自定义持续时间(两秒)的转换由chrono库自动完成.这比以下简单得多:
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
Run Code Online (Sandbox Code Playgroud)
最后,您只需使用.count()成员函数打印出结果.这又比以下简单得多:
std::cout << "seconds since start: " << ((double) difference / 1000000);
Run Code Online (Sandbox Code Playgroud)
但是,由于您对精确度不满意std::chrono::steady_clock,并且您可以访问QueryPerformanceCounter,因此您可以做得更好.您可以在QueryPerformanceCounter之上构建自己的时钟.
<disclaimer>
我没有Windows系统来测试以下代码.
</disclaimer>
struct my_clock
{
typedef double rep;
typedef std::ratio<1> period;
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<my_clock> time_point;
static const bool is_steady = false;
static time_point now()
{
static const long long frequency = init_frequency();
long long t;
QueryPerformanceCounter(&t);
return time_point(duration(static_cast<rep>(t)/frequency));
}
private:
static long long init_frequency()
{
long long f;
QueryPerformanceFrequency(&f);
return f;
}
};
Run Code Online (Sandbox Code Playgroud)
既然你想要你的输出以两秒钟的速度表示,我已经把rep这个时钟变为a double和period1秒.您可以轻松地制作rep积分和period其他一些单位,如微秒或纳秒.您只需将typedefs和转换调整QueryPerformanceCounter为您的durationin now().
现在您的代码看起来很像原始代码:
int main()
{
auto start = my_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = my_clock::now();
auto difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
但是,没有手工编码的转换系数,并与(就是我希望是)足够的精度满足您的需求.并且有一个更容易的移植路径到未来的std::chrono::steady_clock实现.
<chrono>被设计成一个可扩展的库.请延长它.:-)
在 MSVC2012 上运行一些测试后,我可以确认 Microsoft 实现中的 C++11 时钟没有足够高的分辨率。有关此问题的错误报告,请参阅C++ 标头的 high_resolution_clock 没有高分辨率。
因此,不幸的是,对于更高分辨率的计时器,您将需要boost::chrono像这样直接使用 QueryPerformanceCounter ,直到他们修复错误:
#include <iostream>
#include <Windows.h>
int main()
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
LARGE_INTEGER start;
QueryPerformanceCounter(&start);
// Put code here to time
LARGE_INTEGER end;
QueryPerformanceCounter(&end);
// for microseconds use 1000000.0
double interval = static_cast<double>(end.QuadPart- start.QuadPart) /
frequency.QuadPart; // in seconds
std::cout << interval;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2299 次 |
| 最近记录: |