boost::chrono nanoseconde windows7

2019-05-11 04:10发布

问题:

#include <boost/chrono.hpp>

int main()
{ 
    boost::chrono::high_resolution_clock::time_point start = boost::chrono::high_resolution_clock::now();

    //burn some time

    boost::chrono::nanoseconds ns = boost::chrono::high_resolution_clock::now() - start;

    auto val = ns.count();
}

Under Windows 7 64 bits and boost 1.48 could I be sure that the above code will well return me a time in nanosecond/with nanosecond precision ?

EDIT: After doing some test :

  #include <boost/chrono.hpp>
    #include <windows.h>

    double PCFreq = 0.0;
    __int64 CounterStart = 0;

    void StartCounter()
    {
        LARGE_INTEGER li;
        if(!QueryPerformanceFrequency(&li))
            std::cout << "QueryPerformanceFrequency failed!\n";

        PCFreq = double(li.QuadPart)/1000.0;

        QueryPerformanceCounter(&li);
        CounterStart = li.QuadPart;
    }
    double GetCounter()
    {
        LARGE_INTEGER li;
        QueryPerformanceCounter(&li);
        return double(li.QuadPart-CounterStart)/PCFreq;
    }

    int main()
    {
        boost::chrono::high_resolution_clock::time_point start = boost::chrono::high_resolution_clock::now();
        Sleep(1000);
        boost::chrono::nanoseconds sec = boost::chrono::high_resolution_clock::now() - start;   
        std::cout << sec.count()/1000000. <<'\n';

        StartCounter();
        Sleep(1000);
        std::cout << GetCounter() <<'\n';

        std::cin.ignore(); 
    }

both method return approximatively the same result.Something strange about the above code is that first method invoqued in the main will always return the best result, switch boost in second position and GetCounter will be the best (i.e: more closer to Sleep duration)

回答1:

As I delve through the docs, it looks like the difference between two times returns a duration, and that high_resolution_clock might be a system_clock or a steady_clock (depending on if the OS's API has a steady clock). steady_clock::duration is nanoseconds. system_clock docs say "The nested duration typedef has a resolution that depends on the one provided by the platform."

However, the duration type is able to convert between units. So sec will always be in nanoseconds, but there's no guarantee that it will be accurate to the nanosecond that I can find.

On the undocumented details, http://www.boost.org/doc/libs/1_48_0/boost/chrono/system_clocks.hpp shows that when BOOST_CHRONO_WINDOWS_API is defined, the resolution is 100ns, and for all other APIs resolution is 1ns. The result is in all cases stored as nanoseconds, so you don't ever have to worry about conversions.



回答2:

You can be certain that sec is in nanoseconds. E.g. if the value is 1000 then it means 1000 nanoseconds. This is what you get with the type safety in the chrono library; If it compiles then you have nanoseconds. N.B. It's technically possible that a clock is using a shorter period than nanoseconds, e.g. attoseconds, and then the program wouldn't compile, because it wouldn't be able to statically guarantee an exact conversion to nanoseconds.

What you can't be certain of is that the clock actually has a resolution of nanoseconds or is using nanoseconds as its tick period (although the boost implementation of the chrono library may make that guarantee, it's not necessarily true of other implementations of the chrono library). For example the clock may be using milliseconds, and so when you get the duration between two time points and convert it to nanoseconds you would always get a multiple of 1000000 nanoseconds.



标签: c++ boost