2015-05-14 4 views
3

Я ищу кросс-платформенные часы с высоким разрешением, высокой точностью и относительно низкой производительностью (в порядке важности).Часы с высоким разрешением в VS2013

Я пробовал:

//using namespace std::chrono; 
//typedef std::chrono::high_resolution_clock Clock; 

using namespace boost::chrono; 
typedef boost::chrono::high_resolution_clock Clock; 
auto now = Clock::now().time_since_epoch(); 
std::size_t secs = duration_cast<seconds>(now).count(); 
std::size_t nanos = duration_cast<nanoseconds>(now).count() % 1000000000; 
std::time_t tp = (std::time_t) secs; 
std::string mode; 
char timestamp[] = "yyyymmdd HH:MM:SS"; 
char format[] = "%Y%m%d %H:%M:%S"; 

strftime(timestamp, 80, format, std::localtime(&tp)); // Takes 12 microseconds 
std::string output = timestamp + "." + std::to_string(nanos); 

После некоторых исследований и испытаний: Оригинального станд :: хроно :: high_resolution_clock является ЬурейиМ к system_clock и имеет точность примерно 1 миллисекунду. Функция boost :: chrono :: high_resolution_clock использует Query_Performance_Counter для Windows и имеет высокое разрешение и точность. К сожалению, Clock :: now() возвращает время с момента загрузки и теперь(). Time_since_epoch() не возвращает время эпохи (также возвращает время с момента загрузки).

Не против использования защитных устройств для различных решений на разных платформах (требуется VS2013 и Linux). Скорее всего, сохранить сейчас и выполнить обработку в отдельном/низкоприоритетном потоке.

Существует ли межплатформенный высокоточный высокопроизводительный таймер с высокой разрешающей способностью?

Is boost :: chrono :: high_resolution_clock :: now(). Time_since_epoch() работает по назначению? Это не дает времени с последней эпохи. Это дает только время с момента последней загрузки. Есть ли способ преобразовать это сейчас() в секунды с эпохи.

+0

Добавлен вопрос. Глядя на форсированный документ, кажется, что эпоха может быть произвольно определена. Но тогда нет независимого от часов способа преобразования времени_since_epoch в эпоху unix эпохи (обычно называемой эпохой 1970). – user2411693

+0

Помогает ли этот вопрос и ответы? [C++ кросс-платформенный таймер с высоким разрешением] (https://stackoverflow.com/questions/1487695/c-cross-platform-high-resolution-timer)? – Neitsa

+0

Этот пост решает проблему получения времени между двумя точками (таймеры). Мне удобно вычитать любые часы, чтобы найти прошедшее время. То, что я хочу, - это возможность создавать временные метки, которые являются yyyymmdd HH: MM: SS.NNNNNNNNN, где часть наносекундов внутренне согласована (для которой требуется постоянный_clock/QPC), а время - правильное системное время. – user2411693

ответ

-1

Я думаю, что самый лучший способ сделать это - реализовать новый тип часов, который моделирует требование Clock в стандарте C++ 11/14.

Функция окон GetSystemTimePreciseAsFileTime может использоваться как основа для работы с окнами. Я считаю, что эта функция возвращает время в единицах 100 наносекунд с начала эпохи окон. Если я ошибаюсь, просто измените определение period.

struct windows_highres_clock 
{ 
    // implement Clock concept 
    using rep = ULONGLONG; 
    using period = std::ratio<1, 10000000>; 
    using duration = std::chrono::duration<rep, period>; 
    using time_point = std::chrono::time_point<windows_highres_clock, duration>; 

    static constexpr const bool is_steady = true; 

    static time_point now() noexcept { 
     FILETIME ft = { 0, 0 }; 
     GetSystemTimePreciseAsFileTime(&ft); 
     ULARGE_INTEGER stamp { { ft.dwLowDateTime, ft.dwHighDateTime } }; 
     return time_point { duration { stamp.QuadPart } }; 
    } 
}; 

Если вы хотите продолжить реализацию концепции TrivalClock поверх нее, это должно сработать. Просто следуйте инструкциям на странице http://cppreference.com

Предоставление функций_по_о_ и_____________________________________________________________RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU_RU.doc

Пример использование:

windows_highres_clock clock; 
auto t0 = clock.now(); 
sleep(1); 
auto t1 = clock.now(); 
auto diff = t1 - t0; 
auto ms = std::chrono::duration_cast<chrono::milliseconds>(diff); 
cout << "waited for " << ms.count() << " milliseconds\n"; 

пример вывод:

waited for 1005 milliseconds 

для не-Windows систем system_clock обычно хватает, но вы можете написать подобную для каждой системы часы, используя соответствующее нативное время механизмы.

FYI:

Вот портативный кусок кода, который вы можете использовать, чтобы проверить часы решения. Класс any_clock является полиморфным контейнером, который может содержать любой объект, похожий на часы. Он всегда возвращает свои метки времени как микросекунды с эпохи.

// create some syntax to help specialise the any_clock 
template<class Clock> struct of_type {}; 

// polymorphic clock container 
struct any_clock 
{ 

    template<class Clock> 
    any_clock(of_type<Clock>) 
    : _ptr { new model<Clock> {} } 
    {} 

    std::chrono::microseconds now() const { 
     return _ptr->now(); 
    } 

    using duration = std::chrono::microseconds; 

private: 
    struct concept { 
     virtual ~concept() = default; 
     virtual duration now() const noexcept = 0; 
    }; 
    template<class Clock> 
    struct model final : concept { 
     duration now() const noexcept final { 
      return std::chrono::duration_cast<std::chrono::microseconds>(Clock::now().time_since_epoch()); 
     } 
    }; 
    unique_ptr<concept> _ptr; 
}; 

int main(int argc, const char * argv[]) 
{ 
    any_clock clocks[] = { 
     { of_type<windows_highres_clock>() }, 
     { of_type<std::chrono::high_resolution_clock>() }, 
     { of_type<std::chrono::system_clock>() } 
    }; 

    static constexpr size_t nof_clocks = std::extent<decltype(clocks)>::value; 
    any_clock::duration t0[nof_clocks]; 
    any_clock::duration t1[nof_clocks]; 

    for (size_t i = 0 ; i < nof_clocks ; ++i) { 
     t0[i] = clocks[i].now(); 
    } 
    sleep(1); 
    for (size_t i = 0 ; i < nof_clocks ; ++i) { 
     t1[i] = clocks[i].now(); 
    } 
    for (size_t i = 0 ; i < nof_clocks ; ++i) { 
     auto diff = t1[i] - t0[i]; 
     auto ms = std::chrono::duration_cast<chrono::microseconds>(diff); 
     cout << "waited for " << ms.count() << " microseconds\n"; 
    } 
    return 0; 
} 
+0

Примечание: 'GetSystemTimePreciseAsFileTime' доступен только для Windows 8 и выше. – dewaffled

Смежные вопросы