std::chrono::xxx_clockの分解能
もう一つ、Visual C++ 12(Visual Studio 2013)との違いを<chrono>に見つけました。
<chrono>はC++11で導入された、時刻と時間を扱うライブラリです。名前空間std::chronoにあるのは、時を刻む時計に相当するclock、時計によって計測される時刻を表すtime_point、そして2つの時刻の差すなわち時間:duration。clockには3つのバリエーション:system_clock、steady_clock、high_resolution_clockが定義されています。
system_clockが返すtime_pointは、Cの標準関数time()が返すtime_tに変換することができ、実世界と同じ時を刻みます。
using namespace std; chrono::system_clock::time_point time = chrono::system_clock::now(); time_t system_time = chrono::system_clock::to_time_t(time); cout << ctime(&system_time) << endl;
steady_clockは、現在時刻を返すstaticメンバ関数now()によって得られた2つのtime_point t0, t1があるとき、t1がt0より後に得られたものであればt1 >= t0が保証され、t1 - t0は常に正(または0)なので正しい時間が得られます。
high_resolution_clockは、その名のとおり高分解能クロックで、steady_clock以上の分解能であることが保証されます。
これらclockの分解能を実測するコードを書きました:
#include <iostream> #include <chrono> #include <typeinfo> #include <ctime> template<typename Clock> void resolution() { using namespace std; cout << typeid(Clock).name() << endl; for (int i = 0; i < 5; ++i) { Clock::time_point t0 = Clock::now(); Clock::time_point t1; do { t1 = Clock::now(); } while ( t0 == t1 ); cout << chrono::duration_cast<chrono::nanoseconds>(t1 - t0).count() << " [ns]\t" << chrono::duration_cast<chrono::microseconds>(t1 - t0).count() << " [micro-s]" << endl; } cout << endl; } int main() { using namespace std; chrono::system_clock::time_point time = chrono::system_clock::now(); time_t system_time = chrono::system_clock::to_time_t(time); cout << ctime(&system_time) << endl; resolution<chrono::system_clock>(); resolution<chrono::steady_clock>(); resolution<chrono::high_resolution_clock>(); }
これをVisual C++ 12でコンパイル/実行すると:
あれま、どれも0.5ミリ秒の分解能、これより小さな時間を測ることができません。Visual C++ 12ではhigh_resolution_clockは名ばかりの高分解能クロックで、アルゴリズムの違いによる処理時間の差を調べるような目的には使いづらいのです。
一方、Visual C++ 14だと:
300ナノ秒(0.3マイクロ秒)だそうな。この値、Windowsの高精度カウンタ:PerformanceCounterの分解能と同じです。
#include <iostream> #include <windows.h> int main() { using namespace std; LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); cout << 1.0 / freq.QuadPart << endl; }
Visual C++ 14ではPerformanceCounterをclockの実装に使ってくれてるんですね。すばらしい。これなら処理時間をマイクロ秒単位で計測できます。
……なかなか触る時間のないなかで、ひとまず見つけたVisual C++ 14の新しいトピックでした。もちろん本命はWindows 10対応のUWP(Universal Windows Platform)あたりなのでしょうが、こんなところにもVisual C++の進化が見え隠れしてますよ、ってオハナシでした。