したがって、正確なタイミングは私にとって重要であり、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 カーネルにはユーザーがアクセスできるクロックが 1 つしかないのでしょうか?
2 番目の驚きは、これが非常に大きいことですが、steady_clock::is_steady == falseです。定義上、そのプロパティは true であると確信しています。何を与える?? どうすれば回避できますか (つまり、安定したクロックを達成できますか)。
他のプラットフォーム/コンパイラで簡単なプログラムを実行できる場合は、結果を知りたいです. 疑問に思っている人がいれば、私の Core i7 では約 25 ns/反復、Tegra 2 では 1000 ns/反復です。