SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

Visual C++ 14で見つけた<experimental>(試験的)な機能

  • X ポスト
  • このエントリーをはてなブックマークに追加

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に変換することができ、実世界と同じ時を刻みます。

list08
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の分解能を実測するコードを書きました:

list09
#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の分解能と同じです。

list10
#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++の進化が見え隠れしてますよ、ってオハナシでした。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/9084 2015/11/30 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング