Tak dokładne ustawienie jest dla mnie ważne, a ja badałem 3 typy zegarów określone w C++ 11, a mianowicie system_clock
, steady_clock
i high_resolution_clock
. Moją początkową obawą było sprawdzenie, czy istnieje różnica w obciążeniu połączenia dla różnych typów zegarów i sprawdzenie rozdzielczości każdego typu zegara. Oto mój przykładowy program:C++ 11 zegarów: 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;
}
skompilować go z
$ 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]
skompilowany zg ++ 4.7.2, a prowadził ją na
- SUSE Linux kernel v3.1.10 , CPU i7
- Wbudowany system Angstrom Linux, jądro v3.1.10, MCU Tegra 2 (ARM Cortex A9).
Pierwszym zaskoczeniem było to, że 3 rodzaje zegara są najwyraźniej synonimami. Wszystkie mają ten sam okres (1 mikro sekunda), a czas/połączenie są praktycznie takie same. Jaki jest sens określania 3 typów zegarów, jeśli wszystkie są takie same? Czy to dlatego, że implementacja G ++ z chrono
nie jest jeszcze dojrzała? A może jądro 3.1.10 ma tylko jeden zegar dostępny dla użytkownika?
Drugą niespodzianką, która jest ogromna, jest to, że steady_clock :: is_steady == false. Jestem prawie pewien, że z definicji ta własność powinna być prawdziwa. Co daje?? Jak mogę obejść to (tj. Osiągnąć stały zegar)?
Jeśli możesz uruchomić prosty program na innych platformach/kompilatorach, byłbym bardzo zainteresowany poznaniem wyników. Jeśli ktoś zastanawia się, to około 25 ns/iteracji na moim Core i7 i 1000 NS/iteracja na Tegra 2.
Umm, tak. Właśnie kompiluję kod 3 razy, raz dla każdego typu zegara, który jest określony przez flagę '-DXXX'. Ostatnim argumentem na 'g ++' jest nazwa pliku wykonywalnego, która nie ma znaczenia. (chociaż mam to odzwierciedla zarówno typ zegara, jak i fakt, że program wykonuje bibliotekę chrono). –
Przepraszamy, całkowicie błędnie przeczytałem wiersz polecenia –