所以准确的时序对我来说很重要,我正在研究 C++ 11 中指定的 3 种时钟类型,即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: %s\n", 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)。
第一个令人惊讶的是,这 3 种时钟显然是同义词。它们都具有相同的周期(1 微秒),并且时间/呼叫实际上是相同的。如果它们都相同,那么指定 3 种类型的时钟有什么意义?这仅仅是因为G++的实现chrono
还不成熟吗?或者 3.1.10 内核可能只有一个用户可访问的时钟?
第二个惊喜,这是巨大的,是stable_clock::is_steady == false。我相当肯定,根据定义,该属性应该是正确的。是什么赋予了??我该如何解决它(即,实现稳定的时钟)?
如果你可以在其他平台/编译器上运行这个简单的程序,我很想知道结果。如果有人想知道,我的 Core i7 上大约是 25 ns/迭代,而 Tegra 2 上大约是 1000 ns/迭代。