C++11 clocks: g++ steady_clock::is_steady == false?
C++11 clocks: g++ steady_clock::is_steady == false?
所以准确的计时对我来说很重要,我研究了C++11中指定的三种类型的时钟,即system_clock
、steady_clock
和high_resolution_clock
。我最初关心的是测试不同类型时钟的调用开销是否存在差异,并检查每种类型时钟的分辨率。这是我的示例程序:
#include <chrono>
#include <cstdio>
using namespace std;
using namespace std::chrono;
int main(int argc, char **argv)
{
size_t N = 1e6;
if(2 == argc) {
sscanf(argv[1], "%zu", &N);
}
#if defined(hrc)
typedef high_resolution_clock clock;
#warning "High resolution clock"
#elif defined(sc)
typedef steady_clock clock;
#warning "Steady clock"
#elif defined(sys)
typedef system_clock clock;
#warning "System clock"
#endif
const double resolution = double(clock::period::num) / double(clock::period::den);
printf("clock::period: %lf us.n", resolution*1e6);
printf("clock::is_steady: %sn", clock::is_steady ? "yes" : "no");
printf("Calling clock::now() %zu times...n", N);
// first, warm up
for(size_t i=0; i<100; ++i) {
time_point<clock> t = clock::now();
}
// loop N times
time_point<clock> start = clock::now();
for(size_t i=0; i<N; ++i) {
time_point<clock> t = clock::now();
}
time_point<clock> end = clock::now();
// display duration
duration<double> time_span = duration_cast<duration<double>>(end-start);
const double sec = time_span.count();
const double ns_it = sec*1e9/N;
printf("That took %lf seconds. That's %lf ns/iteration.n", sec, ns_it);
return 0;
}
我用编译它
$ g++-4.7 -std=c++11 -Dhrc chrono.cpp -o hrc_chrono
chrono.cpp:15:2: warning: #warning "High resolution clock" [-Wcpp]
$ g++-4.7 -std=c++11 -Dsys chrono.cpp -o sys_chrono
chrono.cpp:15:2: warning: #warning "System clock" [-Wcpp]
$ g++-4.7 -std=c++11 -Dsc chrono.cpp -o sc_chrono
chrono.cpp:15:2: warning: #warning "Steady clock" [-Wcpp]
我用G++4.7.2编译,并在上运行
- SUSE Linux,内核v3.1.10,CPU i7
- Angstrom Linux嵌入式系统,内核v3.1.10,MCU Tegra 2(ARM Cortex A9)
第一件令人惊讶的事情是,这三种类型的时钟显然是同义词。它们都有相同的周期(1微秒),并且时间/呼叫实际上是相同的如果三种类型的时钟都相同,那么指定它们有什么意义这只是因为chrono
的G++实现还不成熟吗?或者3.1.10内核只有一个用户可访问的时钟?
第二个惊喜是steady_clock::is_stady==false。我相当确信,根据定义,这个性质应该是真的。什么给予??我怎样才能绕过它(使时钟稳定)?
如果你能在其他平台/编译器上运行这个简单的程序,我很想知道结果。如果有人想知道,在我的酷睿i7上大约是25纳秒/次,在Tegra 2上大约是1000纳秒/次。
steady_clock
(如4.7版本的文档所示:http://gcc.gnu.org/onlinedocs/gcc-4.7.2/libstdc++/manual/manual/status.html#status.iso.2011)和steady_clock::is_steady
是真的,但前提是您使用--enable-libstdcxx-time=rt
构建GCC
请参阅https://stackoverflow.com/a/12961816/981959有关该配置选项的详细信息。
对于GCC 4.9,如果您的操作系统和C库支持clock_gettime
的POSIX单调时钟,它将自动启用(对于带有glibc 2.17或更高版本的GNU/Linux以及Solaris 10、IIRC,这是正确的)
以下是在AMD Phenom II X4 905e上配置--enable-libstdcxx-time=rt
的GCC 4.8的结果,2.5GHz,但我认为它现在已经被抑制到800MHz,运行Linux 3.6.11,glibc 2.15
$ ./hrc
clock::period: 0.001000 us.
clock::is_steady: no
Calling clock::now() 1000000 times...
That took 0.069646 seconds. That's 69.645928 ns/iteration.
$ ./sys
clock::period: 0.001000 us.
clock::is_steady: no
Calling clock::now() 1000000 times...
That took 0.062535 seconds. That's 62.534986 ns/iteration.
$ ./sc
clock::period: 0.001000 us.
clock::is_steady: yes
Calling clock::now() 1000000 times...
That took 0.065684 seconds. That's 65.683730 ns/iteration.
在运行Linux 3.4.0、glibc 2.16 的ARMv7 Exynos5上,使用GCC 4.7而不使用--enable-libstdcxx-time
(因此所有三种时钟类型的结果相同)
clock::period: 1.000000 us.
clock::is_steady: no
Calling clock::now() 1000000 times...
That took 1.089904 seconds. That's 1089.904000 ns/iteration.
如果你能在其他平台/编译器上运行这个简单的程序,我我很想知道结果。
Mac OS X 10.8,clang++/libc++,-O3,2.8 GHz酷睿i5:
High resolution clock
clock::period: 0.001000 us.
clock::is_steady: yes
Calling clock::now() 1000000 times...
That took 0.021833 seconds. That's 21.832827 ns/iteration.
System clock
clock::period: 1.000000 us.
clock::is_steady: no
Calling clock::now() 1000000 times...
That took 0.041930 seconds. That's 41.930000 ns/iteration.
Steady clock
clock::period: 0.001000 us.
clock::is_steady: yes
Calling clock::now() 1000000 times...
That took 0.021478 seconds. That's 21.477953 ns/iteration.
CCD_ 11和CCD_。要求CCD_ 13为CCD_。CCD_ 15可以是CCD_ 16或CCD_。system_clock::rep
必须是签名类型。
根据GNU的网站,GNU libstdc++还不支持steady_clock
。这就是steady_clock::is_steady
为假的原因。
以下是支持清单的相关部分:
20.11.7.1 Class system_clock Y
20.11.7.2 Class steady_clock N Support old monotonic_clock spec instead
20.11.7.3 Class high_resolution_clock Y
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 伪造事实↔false
- QueryWorkingSet总是返回false
- 如何区分地图中的 0 和 false?
- 模板参数列表中的 false 在模板初始化期间计算为什么?
- Arduino-C++ bool 不会从 false 变为 true
- 当返回类型声明为 ListNode 时,我们是否可以返回 false<T>*
- 当我的 if 条件计算结果为 false 时,我的 else 块将不会执行
- 等于在 c++ 中返回 false
- strcmp 对于相等的字符序列返回 false
- std::is_class 在引用类上为 false
- ios_base::sync_with_stdio(false); cin.tie(NULL);
- C++ - 负数和正数之间的比较返回 false
- 如何使用boost定义布尔类,可能的值应该是TRUE或FALSE?
- 如何编写一个接受如下断言消息的自定义断言函数:assert(false) << "assertio
- protobuf 的 ParseFromString 函数返回 false
- WaitForMultipleObjects when bwaitall is false
- 跳转到if(false)块有问题吗
- 为什么当 while 循环中的 if 条件变为 false 时,我的函数不输出最后一条语句?
- 为什么将三个变量与 == 一起比较会计算为 false?