So genaues Timing ist wichtig für mich, und ich war die Untersuchung der drei Arten von Uhren angegeben in C++ 11, nämlich system_clock
, steady_clock
und high_resolution_clock
. Meine erste Sorge war zu testen, ob es einen Unterschied im Anruf-Overhead zu den verschiedenen Arten von Uhren gibt, und um die Auflösung von jedem Typ von Uhr zu überprüfen. Hier ist mein Beispielprogramm:C++ 11 Takte: g ++ steady_clock :: is_steady == false?
#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;
}
ich kompilieren es mit
$ 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]
ich mit G ++ kompiliert 4.7.2, und es lief auf
- SUSE Linux Kernel v3.1.10 , CPU i7
- Angstrom Linux eingebettetes System, Kernel v3.1.10, MCU Tegra 2 (ARM Cortex A9).
Die erste überraschende Sache war, dass die 3 Arten der Uhr anscheinend Synonyme sind. Sie alle haben die gleiche Periode (1 Mikrosekunde), und die Zeit/Anruf ist praktisch gleich. Was ist der Sinn der Angabe von 3 Arten von Uhren, wenn sie alle gleich sind? Ist das nur, weil die G ++ - Implementierung von chrono
noch nicht ausgereift ist? Oder vielleicht hat der 3.1.10 Kernel nur eine benutzerzugängliche Uhr?
Die zweite Überraschung, und das ist riesig, ist, dass steady_clock :: is_steady == false. Ich bin ziemlich sicher, dass diese Eigenschaft per Definition wahr sein sollte. Was gibt?? Wie kann ich das umgehen (dh eine stabile Uhr erreichen)?
Wenn Sie das einfache Programm auf anderen Plattformen/Compilern ausführen können, wäre ich sehr interessiert, die Ergebnisse zu kennen. Wenn jemand fragt, es ist etwa 25 ns/Iteration auf meinem Core i7 und 1000 ns/Iteration auf den Tegra 2.
Umm, yeah. Ich kompiliere den Code nur 3 Mal, einmal für jede Art von Uhr, die durch das '-DXXX'-Flag spezifiziert wird. Das letzte Argument zu 'g ++' ist nur der Dateiname der ausführbaren Datei, was keinen Unterschied macht. (obwohl ich es sowohl die Art der Uhr und die Tatsache reflektieren, dass das Programm die Chrono-Bibliothek ausübt.) –
Sorry, ich habe die Befehlszeile komplett falsch gelesen –