high_resolution_clock的最高分辨率是1000ns

时间:2014-05-24 10:11:49

标签: c++ gcc c++11 gcc4 chrono

我正在做涉及基准测试算法的工作。 我在C ++ 11中读到了新的<chrono>标题,所以我接受了。

我可以采取测量和一切,但我正在努力解决。

做类似

的事情
auto duration = chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();

我总是得到倍数为1000的倍数!

进一步调查并做以下

cout << (double) chrono::high_resolution_clock::period::num / 
chrono::high_resolution_clock::period::den << endl;

我得到的值1e-06是微秒,不是纳秒。它投射到纳秒很好,但是如果时钟的周期只是以微秒开始就没用了。

我是迂腐吗?我知道我可以多次运行我的测试代码并获得很长的平均工作时间,这就是我正在做的事情。但这对我来说几乎是一个原则问题。

额外信息: 我在Ubuntu 12.04服务器X64上使用最新版本的GCC(4.6.3)(我认为)

3 个答案:

答案 0 :(得分:3)

Fwiw,对我来说,这个:

#include <ratio>
#include <chrono>
#include <string>

template <class Ratio, class CharT>
struct ratio_string
{
    static std::basic_string<CharT> symbol()
    {
        return std::basic_string<CharT>(1, CharT('[')) +
               std::to_string(Ratio::num) + CharT('/') +
               std::to_string(Ratio::den) + CharT(']');
    }
};

template <class CharT>
struct ratio_string<std::nano, CharT>
{
    static std::basic_string<CharT> symbol()
    {
        return std::basic_string<CharT>(1, CharT('n'));
    }
};

template <>
struct ratio_string<std::micro, char>
{
    static std::string symbol() {return std::string("\xC2\xB5");}
};

template <>
struct ratio_string<std::micro, char16_t>
{
    static std::u16string symbol() {return std::u16string(1, u'\xB5');}
};

template <>
struct ratio_string<std::micro, char32_t>
{
    static std::u32string symbol() {return std::u32string(1, U'\xB5');}
};

template <>
struct ratio_string<std::micro, wchar_t>
{
    static std::wstring symbol() {return std::wstring(1, L'\xB5');}
};

template <class CharT, class Rep, class Period>
inline
std::basic_string<CharT>
get_unit(const std::chrono::duration<Rep, Period>& d)
{
    return ratio_string<Period, CharT>::symbol() + 's';
}

template <class Rep, class Period>
std::string
to_string(const std::chrono::duration<Rep, Period>& d)
{
    return std::to_string(d.count()) + get_unit<char>(d);
}

#include <iostream>

int
main()
{
    auto t0 = std::chrono::high_resolution_clock::now();
    auto t1 = std::chrono::high_resolution_clock::now();
    std::cout << to_string(t1-t0) << '\n';
}

使用-O3编译时,输出:

$ a.out
112ns
$ a.out
95ns
$ a.out
112ns
$ a.out
111ns

YMMV。如果您添加ratio_string专精,则输出可能更整洁。

答案 1 :(得分:2)

时钟的精度依赖于硬件和操作系统,在运行linux微秒的x86平台上是很正常的。在我的红帽6和2.6.30内核上,我只能得到大约10μs。

要获得更好的分辨率,您需要一个实时操作系统。

答案 2 :(得分:0)

  

我的印象是,duration_cast实际上会给我纳秒,而不仅仅是那些特定实现的维护者在MSVC ++案例中决定做的事情。

不,duration_cast只会将持续时间原样转换为其他类型。它不会改变内部时钟的工作方式或改变时钟的分辨率。

一般来说,最好不要进行这些演员表或转换,而只是让实现选择合适的类型。它也比较简单:

auto duration = end_time - start_time;

使用Howard Hinnant的chrono_io,您可以直接将其打印出来,它会为您提供合适的单位。

std::cout << duration << '\n';

根据实际分辨率,这会打印出112ns2us等内容。