2014-09-23 227 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時鐘ID的呼叫數量級比調用更快使用時鐘ID CLOCK_MONOTONIC。

下面是測試運行,要求clock_gettime一百萬次在緊密循環和測量以毫秒爲單位經過時間的示例輸出:

CLOCK_MONOTONIC lapse 795 
CLOCK_MONOTONIC_COARSE lapse 27 

這讓我高興,使探查結果更好看,但是我希望我可以使用std :: chrono或boost :: chrono來提高可移植性和標準一致性,而不會犧牲這個速度。不幸的是,我沒有找到任何方法說服chrono(任何一個)在CLOCK_MONOTONIC_COARSE可用時使用。我嘗試了chrono :: steady_clock,但結果與CLOCK_MONOTONIC值相當。

有沒有一種方法可以指定計時器,你願意犧牲精度的速度?

+0

哪個'性病之一:: chrono ::'時鐘你用過嗎? – 5gon12eder 2014-09-23 19:44:09

+0

@ 5gon12eder:我剛剛編輯了問題以表明我試過了std :: chrono :: steady_clock – 2014-09-23 19:45:28

+4

如果您知道'CLOCK_MONOTONIC_COARSE'的特性,您可以輕鬆地在其周圍構建自己的自定義時鐘式時鐘。你只需要幾個'typedef'和一個'now()'函數。 – 2014-09-23 19:51:06

回答

3

由於Howard said這是簡單的讓你自己的時鐘 - 一種符合C++ 11 Clock要求 - 使用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); 
}