Я ищу реализовать простой механизм таймера в C++. Код должен работать в Windows и Linux. Разрешение должно быть максимально точным (точность не менее миллисекунды). Это будет использоваться для простого отслеживания времени, а не для реализации какого-либо проекта, управляемого событиями. Каков наилучший инструмент для этого?C++ Кросс-платформенный таймер с высоким разрешением
ответ
Для C++ 03:
Boost.Timer может работать, но зависит от функции C clock
и поэтому может не иметь достаточно хорошего разрешения для вас.
Boost.Date_Time включает в себя ptime
class, который ранее был рекомендован для переполнения стека. См. Его документы на microsec_clock::local_time
и microsec_clock::universal_time
, но обратите внимание на его предупреждение о том, что «системы Win32 часто не достигают разрешения микросекунд через этот API».
STLsoft предлагает, среди прочего, тонкие кросс-платформенные (Windows и Linux/Unix) C++-оболочки вокруг API-интерфейсов, специфичных для ОС. Его performance library имеет несколько классов, которые будут делать то, что вам нужно. (Чтобы сделать это кросс-платформенный, выбрать класс, как performance_counter
, который существует в обоих winstl
и unixstl
пространств имен, а затем использовать в зависимости от того пространства имен соответствует вашей платформы.)
Для C++ 11 и выше:
В библиотеке std::chrono
встроена эта функциональность. Подробнее см. this answer от @HowardHinnant.
Поскольку это известный вопрос/ответ, обновление может быть отличным. В частности, это может быть достигнуто стандартным и переносимым образом с использованием современных возможностей C++, таких как '
Первый ответ на вопросы библиотеки C++, как правило, BOOST: http://www.boost.org/doc/libs/1_40_0/libs/timer/timer.htm. Делает ли это то, что вы хотите? Наверное, но это не начало.
Проблема в том, что вы хотите, чтобы портативные и таймерные функции не были универсальными в ОС.
StlSoft библиотека с открытым исходным кодом обеспечивает довольно good timer как на окнах, так и на платформах Linux. Если вы хотите, чтобы он реализовывался самостоятельно, просто посмотрите на их источники.
Я не уверен, что ваше требование, если вы хотите, чтобы вычислить интервал времени см нить ниже
В библиотеке ACE также имеются портативные таймеры с высоким разрешением.
Doxygen для высокого Рез таймера:
http://www.dre.vanderbilt.edu/Doxygen/5.7.2/html/ace/a00244.html
Я видел это реализовано несколько раз с закрытыми исходными растворами в доме .... которые все прибегали к #ifdef
решений вокруг родных для Windows высоком разрешении таймеры, с одной стороны, и таймеры ядра Linux, использующие struct timeval
(см. man timeradd
), с другой стороны.
Вы можете абстрагироваться от этого, и несколько проектов с открытым исходным кодом сделали это - последний, на который я смотрел, был CoinOR class CoinTimer, но, несомненно, их больше.
Я решил пойти по этому маршруту. Ваша ссылка была мертвой, поэтому я прокомментировал тот, который все еще работает: http://www.songho.ca/misc/timer/timer.html – Patrick
Ahh, ничего похожего на комментарий по восьмилетнему вопросу :) У меня была удача тем временем с библиотекой [CCTZ] (https://github.com/google/cctz) из Google, которая основывается на некоторые новые идиомы C++ 11. –
Это не самый лучший ответ, но вот некоторые разговоры на сайте разработки игр относительно таймеров высокого разрешения:
Я очень порекомендуйте boost :: posix_time для этого. Он поддерживает таймеры в различных разрешениях до микросекунд. Я считаю, что
STLSoft имеют Performance Library, который включает в себя набор классов таймера, некоторые из которых работают как для UNIX, так и для Windows.
STLSoft libraries Предоставляются несколько типов таймеров с конгруэнтными интерфейсами, чтобы вы могли подключаться и играть. Среди предложений - таймеры, которые являются недорогими, но с низким разрешением, и те, которые имеют высокое разрешение, но имеют высокую стоимость. Существуют также приборы для измерения времени предварительной обработки и для измерения времени обработки, а также для всех измеряемых истекших периодов времени.
Несколько лет назад существует исчерпывающий article covering it in Dr. Dobb's, хотя он охватывает только те, что описаны в подпроекте WinSTL. STLSoft также предусматривает UNIX таймеров в UNIXSTL подпроекта, и вы можете использовать «PlatformSTL» один, который включает в UNIX или Windows, один, как соответствующий, например:
#include <platformstl/performance/performance_counter.hpp>
#include <iostream>
int main()
{
platformstl::performance_counter c;
c.start();
for(int i = 0; i < 1000000000; ++i);
c.stop();
std::cout << "time (s): " << c.get_seconds() << std::endl;
std::cout << "time (ms): " << c.get_milliseconds() << std::endl;
std::cout << "time (us): " << c.get_microseconds() << std::endl;
}
HTH
Ссылка мертва кстати. – Tek
Обновленный ответ для старого вопроса:
в C++ 11 вы можете переносимо добраться до самого высокого разрешения таймера с:
#include <iostream>
#include <chrono>
#include "chrono_io"
int main()
{
typedef std::chrono::high_resolution_clock Clock;
auto t1 = Clock::now();
auto t2 = Clock::now();
std::cout << t2-t1 << '\n';
}
Пример вывода:
74 nanoseconds
«chrono_io» - это расширение, облегчающее проблемы ввода-вывода с этими новыми типами и свободно доступное here.
Существует также реализация <chrono>
, доступная в boost (все еще может быть на кончике ствола, не уверен, что она была выпущена).
Update
Это в ответ на комментарий Бена ниже, что последующий вызов std::chrono::high_resolution_clock
занять несколько миллисекунд в VS11. Ниже приведено <chrono>
-совместимое обходное решение. Однако это работает только на оборудовании Intel, вам необходимо погрузить в инлайн сборку (синтаксис, чтобы сделать это зависит от компилятора), и вы должны проводным тактовых машин в часы:
#include <chrono>
struct clock
{
typedef unsigned long long rep;
typedef std::ratio<1, 2800000000> period; // My machine is 2.8 GHz
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<clock> time_point;
static const bool is_steady = true;
static time_point now() noexcept
{
unsigned lo, hi;
asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
return time_point(duration(static_cast<rep>(hi) << 32 | lo));
}
private:
static
unsigned
get_clock_speed()
{
int mib[] = {CTL_HW, HW_CPU_FREQ};
const std::size_t namelen = sizeof(mib)/sizeof(mib[0]);
unsigned freq;
size_t freq_len = sizeof(freq);
if (sysctl(mib, namelen, &freq, &freq_len, nullptr, 0) != 0)
return 0;
return freq;
}
static
bool
check_invariants()
{
static_assert(1 == period::num, "period must be 1/freq");
assert(get_clock_speed() == period::den);
static_assert(std::is_same<rep, duration::rep>::value,
"rep and duration::rep must be the same type");
static_assert(std::is_same<period, duration::period>::value,
"period and duration::period must be the same type");
static_assert(std::is_same<duration, time_point::duration>::value,
"duration and time_point::duration must be the same type");
return true;
}
static const bool invariants;
};
const bool clock::invariants = clock::check_invariants();
Так что не портативный. Но если вы хотите поэкспериментировать с часами с высоким разрешением на вашем собственном оборудовании Intel, он не станет более тонким, чем это. Несмотря на это, сегодняшние тактовые частоты могут динамически меняться (они на самом деле не являются постоянной времени компиляции). И с многопроцессорной машиной вы даже можете получать метки времени от разных процессоров. Но все же эксперименты на моем оборудовании работают достаточно хорошо.Если вы застряли с разрешением в миллисекундах, это может быть обходным путем.
Эти часы имеют длительность с точки зрения тактовой частоты вашего процессора (как вы сообщили об этом). То есть для меня эти часы гадают один раз каждые 1/2 800 000 000 секунд. Если вы хотите, вы можете преобразовать это в наносекунды (например) с:
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
auto t0 = clock::now();
auto t1 = clock::now();
nanoseconds ns = duration_cast<nanoseconds>(t1-t0);
Конверсия усечет фракцию цикла процессора для формирования наносекунды. Другие варианты округления возможны, но это другая тема.
Для меня это вернет длительность до 18 тактов, которая усекает до 6 наносекунд.
Я добавил некоторую «проверку инварианта» к вышеуказанным часам, наиболее важным из которых является проверка того, что clock::period
подходит для машины. Опять же, это не переносимый код, но если вы используете эти часы, вы уже это сделали. Частная функция get_clock_speed()
, показанная здесь, получает максимальную частоту процессора на OS X, и это должно быть то же число, что и константный знаменатель clock::period
.
Это позволит вам немного отладить время, когда вы переносите этот код на новый компьютер и забудьте обновить clock::period
до скорости вашей новой машины. Вся проверка выполняется либо во время компиляции, либо во время запуска программы. Таким образом, это не повлияет на производительность clock::now()
.
В Visual Studio 11, к сожалению, кратчайший ненулевой интервал для 'high_resolution_clock' составляет несколько миллисекунд. – Petter
Для меня потребовалось несколько секунд ... миллионы наносекунд на платформе, где тактовая частота составляет долю наносекунды. Вау!!! Я надеялся увидеть платформы, где измеряются фракции наносекунды. Я думал, что мои результаты в несколько десятков наносекунд не впечатляют. –
Да, я действительно представил это как ошибку для Visual Studio 11. Однако, поскольку это не критично, я не ожидаю, что он будет исправлен в этой версии. – Petter
Если в проекте используется каркас Qt, лучшим решением является использование QElapsedTimer.
Поздно к вечеринке здесь, но я работаю в устаревшей кодовой базе, которую нельзя обновить до C++ 11. Никто из нашей команды не имеет особого опыта работы на C++, поэтому добавление библиотеки, такой как STL, оказывается затруднительным (помимо потенциальных проблем, которые другие подняли о проблемах развертывания). Мне действительно нужен был чрезвычайно простой кросс-платформенный таймер, который мог бы жить сам по себе без чего-либо, кроме стандартных системных библиотек с голыми костями. Вот что я нашел:
http://www.songho.ca/misc/timer/timer.html
перепроведении весь источник здесь просто так не заблудиться, если сайт никогда не умирает:
//////////////////////////////////////////////////////////////////////////////
// Timer.cpp
// =========
// High Resolution Timer.
// This timer is able to measure the elapsed time with 1 micro-second accuracy
// in both Windows, Linux and Unix system
//
// AUTHOR: Song Ho Ahn ([email protected]) - http://www.songho.ca/misc/timer/timer.html
// CREATED: 2003-01-13
// UPDATED: 2017-03-30
//
// Copyright (c) 2003 Song Ho Ahn
//////////////////////////////////////////////////////////////////////////////
#include "Timer.h"
#include <stdlib.h>
///////////////////////////////////////////////////////////////////////////////
// constructor
///////////////////////////////////////////////////////////////////////////////
Timer::Timer()
{
#if defined(WIN32) || defined(_WIN32)
QueryPerformanceFrequency(&frequency);
startCount.QuadPart = 0;
endCount.QuadPart = 0;
#else
startCount.tv_sec = startCount.tv_usec = 0;
endCount.tv_sec = endCount.tv_usec = 0;
#endif
stopped = 0;
startTimeInMicroSec = 0;
endTimeInMicroSec = 0;
}
///////////////////////////////////////////////////////////////////////////////
// distructor
///////////////////////////////////////////////////////////////////////////////
Timer::~Timer()
{
}
///////////////////////////////////////////////////////////////////////////////
// start timer.
// startCount will be set at this point.
///////////////////////////////////////////////////////////////////////////////
void Timer::start()
{
stopped = 0; // reset stop flag
#if defined(WIN32) || defined(_WIN32)
QueryPerformanceCounter(&startCount);
#else
gettimeofday(&startCount, NULL);
#endif
}
///////////////////////////////////////////////////////////////////////////////
// stop the timer.
// endCount will be set at this point.
///////////////////////////////////////////////////////////////////////////////
void Timer::stop()
{
stopped = 1; // set timer stopped flag
#if defined(WIN32) || defined(_WIN32)
QueryPerformanceCounter(&endCount);
#else
gettimeofday(&endCount, NULL);
#endif
}
///////////////////////////////////////////////////////////////////////////////
// compute elapsed time in micro-second resolution.
// other getElapsedTime will call this first, then convert to correspond resolution.
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTimeInMicroSec()
{
#if defined(WIN32) || defined(_WIN32)
if(!stopped)
QueryPerformanceCounter(&endCount);
startTimeInMicroSec = startCount.QuadPart * (1000000.0/frequency.QuadPart);
endTimeInMicroSec = endCount.QuadPart * (1000000.0/frequency.QuadPart);
#else
if(!stopped)
gettimeofday(&endCount, NULL);
startTimeInMicroSec = (startCount.tv_sec * 1000000.0) + startCount.tv_usec;
endTimeInMicroSec = (endCount.tv_sec * 1000000.0) + endCount.tv_usec;
#endif
return endTimeInMicroSec - startTimeInMicroSec;
}
///////////////////////////////////////////////////////////////////////////////
// divide elapsedTimeInMicroSec by 1000
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
///////////////////////////////////////////////////////////////////////////////
// divide elapsedTimeInMicroSec by 1000000
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTimeInSec()
{
return this->getElapsedTimeInMicroSec() * 0.000001;
}
///////////////////////////////////////////////////////////////////////////////
// same as getElapsedTimeInSec()
///////////////////////////////////////////////////////////////////////////////
double Timer::getElapsedTime()
{
return this->getElapsedTimeInSec();
}
и заголовочный файл:
//////////////////////////////////////////////////////////////////////////////
// Timer.h
// =======
// High Resolution Timer.
// This timer is able to measure the elapsed time with 1 micro-second accuracy
// in both Windows, Linux and Unix system
//
// AUTHOR: Song Ho Ahn ([email protected]) - http://www.songho.ca/misc/timer/timer.html
// CREATED: 2003-01-13
// UPDATED: 2017-03-30
//
// Copyright (c) 2003 Song Ho Ahn
//////////////////////////////////////////////////////////////////////////////
#ifndef TIMER_H_DEF
#define TIMER_H_DEF
#if defined(WIN32) || defined(_WIN32) // Windows system specific
#include <windows.h>
#else // Unix based system specific
#include <sys/time.h>
#endif
class Timer
{
public:
Timer(); // default constructor
~Timer(); // default destructor
void start(); // start timer
void stop(); // stop the timer
double getElapsedTime(); // get elapsed time in second
double getElapsedTimeInSec(); // get elapsed time in second (same as getElapsedTime)
double getElapsedTimeInMilliSec(); // get elapsed time in milli-second
double getElapsedTimeInMicroSec(); // get elapsed time in micro-second
protected:
private:
double startTimeInMicroSec; // starting time in micro-second
double endTimeInMicroSec; // ending time in micro-second
int stopped; // stop flag
#if defined(WIN32) || defined(_WIN32)
LARGE_INTEGER frequency; // ticks per second
LARGE_INTEGER startCount; //
LARGE_INTEGER endCount; //
#else
timeval startCount; //
timeval endCount; //
#endif
};
#endif // TIMER_H_DEF
- 1. Qt таймер с высоким разрешением
- 2. таймер с высоким разрешением в C++
- 3. Поднять событие с высоким разрешением интервал/таймер
- 4. Таймер с высоким разрешением ObjC/C/C++ с обратным вызовом
- 5. Таймер с высоким разрешением для iPhone?
- 6. Таймеры с высоким разрешением и таймеры с низким разрешением
- 7. iPhone с высоким разрешением
- 8. Таймер с высоким разрешением Linux в многопоточной среде?
- 9. таймер с высоким разрешением замерзает остальную часть моего приложения
- 10. Как получить таймер с высоким разрешением в собственном коде Android?
- 11. C# изображения с высоким разрешением в PDF
- 12. Использование изображений с высоким разрешением
- 13. Холст с высоким разрешением изображения
- 14. Отображаем изображение с высоким разрешением
- 15. Фоновые изображения с высоким разрешением?
- 16. Экспорт изображения с высоким разрешением?
- 17. Создание изображения с высоким разрешением
- 18. ALAsset миниатюр с высоким разрешением
- 19. Дисплей с высоким разрешением изображения
- 20. Потребитель-производитель с высоким разрешением
- 21. Изображение с высоким разрешением - OutOfMemoryError
- 22. setVideoSize() сбой с высоким разрешением
- 23. Часы с высоким разрешением в VS2013
- 24. PDF в PNG с высоким разрешением
- 25. Замените изображение с низким разрешением с высоким разрешением.
- 26. Загрузка версии с высоким разрешением с высоким разрешением с сервера (решение, отличное от javascript)
- 27. Сохраните System.Drawing.Bitmap с высоким разрешением aspx
- 28. Изображение с высоким разрешением с Mapnik
- 29. Уменьшение набора координат с высоким разрешением?
- 30. Поддержка изображений с высоким разрешением и низким разрешением
Будьте более конкретным. Вы выбираете вызов функции или хотите получить какой-то сигнал после определенного периода времени. Это «простые» приложения таймера, но они реализованы по-разному. Обратите внимание: использование «простых» в кавычках: синхронизация в компьютерах общего назначения никогда не бывает «простой». – jmucchiello
C версия http://stackoverflow.com/questions/361363/how-to-measure-time-in-milliseconds-using-ansi-c –