Для меня важно точное время, и я изучал 3 типа часов, указанных в C++ 11, а именно system_clock
, steady_clock
и high_resolution_clock
. Моя первоначальная проблема заключалась в тестировании, если есть какая-либо разница в накладных расходах на разные типы часов и проверка разрешения каждого типа часов. Вот мой пример программы:C++ 11 clocks: g ++ stable_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;
}
я скомпилировать его с
$ 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]
I скомпилированные с 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. Я вполне уверен, что по определению это свойство должно быть истинным. Что дает?? Как я могу обойти это (т. Е. Добиться постоянных часов)?
Если вы можете запустить простую программу на других платформах/компиляторах, мне было бы очень интересно узнать результаты. Если кто-то интересно, это около 25 нс/итерацию на моем Core i7, и 1000 нс/итерация на Tegra 2.
Умм, да. Я просто компилирую код 3 раза, один раз для каждого типа часов, который указан флагом '-DXXX'. Последний аргумент 'g ++' - это только имя исполняемого файла, что не имеет значения. (хотя я думаю, что он отражает как тот тип часов, так и тот факт, что программа использует библиотеку хроно.) –
Извините, я полностью неправильно прочитал командную строку –