2014-09-23 4 views
1

Запуск на Linux (uname говорит :)Std :: хроно или повышение :: поддержка хронографа для CLOCK_MONOTONIC_COARSE

Linux 2.6.32-431.29.2.el6.x86_64 #1 SMP Sun Jul 27 15:55:46 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux 

Мои тесты показывают, что clock_gettime звонки с часами идентификатором CLOCK_MONOTONIC_COARSE являются на порядок быстрее, чем звонки которые используют идентификатор часов CLOCK_MONOTONIC.

Вот пример вывода из теста, который называется clock_gettime один миллион раз в тугой петле и размеренной отступников время в миллисекундах:

CLOCK_MONOTONIC lapse 795 
CLOCK_MONOTONIC_COARSE lapse 27 

Это радует меня и делает результаты профилировщика выглядеть лучше, но я надеялся, что я смогу использовать std :: chrono или boost :: chrono для мобильности и стандартного соответствия, не жертвуя этой скоростью. К сожалению, я не нашел способа убедить хроно (один из них) использовать CLOCK_MONOTONIC_COARSE, когда он доступен. Я пробовал chrono :: stable_clock, но результаты сопоставимы с значениями CLOCK_MONOTONIC.

Есть ли способ указать хроно, что вы готовы жертвовать точностью для скорости?

+0

Какой из 'станда :: chrono :: 'часы вы использовали? – 5gon12eder

+0

@ 5gon12eder: Я только что редактировал вопрос, чтобы указать, что я попробовал std :: chrono :: stable_clock –

+4

Если вы знаете характеристики 'CLOCK_MONOTONIC_COARSE', вы можете легко создавать свои собственные часы в стиле хроно. Вам просто нужны несколько 'typedef' и функция' now() '. –

ответ

3

Как Howard said это просто сделать свои собственные часы - тип, соответствующие требования 11 Clock C++ - который использует CLOCK_MONOTONIC_COARSE, когда он доступен и CLOCK_MONOTONIC в противном случае (Live at Coliru):

class fast_monotonic_clock { 
public: 
    using duration = std::chrono::nanoseconds; 
    using rep = duration::rep; 
    using period = duration::period; 
    using time_point = std::chrono::time_point<fast_monotonic_clock>; 

    static constexpr bool is_steady = true; 

    static time_point now() noexcept; 

    static duration get_resolution() noexcept; 

private: 
    static clockid_t clock_id(); 
    static clockid_t test_coarse_clock(); 
    static duration convert(const timespec&); 
}; 

inline clockid_t fast_monotonic_clock::test_coarse_clock() { 
    struct timespec t; 
    if (clock_gettime(CLOCK_MONOTONIC_COARSE, &t) == 0) { 
     return CLOCK_MONOTONIC_COARSE; 
    } else { 
     return CLOCK_MONOTONIC; 
    } 
} 

clockid_t fast_monotonic_clock::clock_id() { 
    static clockid_t the_clock = test_coarse_clock(); 
    return the_clock; 
} 

inline auto fast_monotonic_clock::convert(const timespec& t) -> duration { 
    return std::chrono::seconds(t.tv_sec) + std::chrono::nanoseconds(t.tv_nsec); 
} 

auto fast_monotonic_clock::now() noexcept -> time_point { 
    struct timespec t; 
    const auto result = clock_gettime(clock_id(), &t); 
    assert(result == 0); 
    return time_point{convert(t)}; 
} 

auto fast_monotonic_clock::get_resolution() noexcept -> duration { 
    struct timespec t; 
    const auto result = clock_getres(clock_id(), &t); 
    assert(result == 0); 
    return convert(t); 
} 

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

  • Нет связанных вопросов^_^