clock()の改造版

  • (by K, 2019.02.08)

(1)

  • C言語の標準関数には以下の関数がある。
    clock_t clock(void);
  • これはとても良い関数だが、結局使いやすくはない。
  • なぜなら、精度は処理系依存だし(だから秒なのかミリ秒なのかマイクロ秒なのかは処理系依存)、だから CLOCKS_PER_SEC というマクロを使って単位を換算することになっているのだけど、プログラマにとって使いやすいのはこういう仕様ではないはずだ。
  • またclock_tの型もどんなものになるのかは処理系依存になっている。だからintかもしれないしlongかもしれないしlong longかもしれない。
  • そうじゃなくてこの関数はこの精度でこれこれのビット幅で値を返すってはっきり言ってくれればいいのだ。そうすれば心配なく使える。そうじゃなければ、clock関数が自分の用途に十分な精度とビット幅があるのか全然わからず、結局確信を持って使うことができない。
  • それでどうするか、そう、ないなら作るまでである。そして将来移植する必要が出てきたら、この関数だけを移植すれば済むということになる。

(2)

long long clkmsec(void);
  • long long で64bit以上になるので、負の数を避けるとしても2.922億年はオーバーフローの心配がありません。
  • ちなみにもしここがlongだったら32bit以上にしかならないので、24.855日後にはオーバーフローの心配があります。
    • 私にとって、25日以上プログラムをずっと走らせるというのはレアではあるもののやることではあるので、 long long であるのは相当な安心感があります。
  • [以下のコードでの暗黙の前提]
    • この関数が十分な頻度で呼び出される。この十分な頻度というのは、clock()が振り切らない程度という意味です。
long long clkmsec_c = 0LL;
clock_t clkmsec_t0 = 0;

long long clkmsec(void)
{
    clock_t t = clock(), dt = t - clkmsec_t0;
    clkmsec_t0 = t;
    clkmsec_c += dt / (CLOCKS_PER_SEC / 1000);
    return clkmsec_c;
}

(3)

long long clkusec(void);
  • long long で64bit以上になるので、負の数を避けるとしても29.22万年はオーバーフローの心配がありません。
  • これはclkmsecが2.9億年まで平気とか言うよりも、29.22万年までにする代わりにマイクロ秒単位にするほうが有用なんじゃないかと思って、このバージョンを作りました。
  • ちなみにもしここがlongだったら32bit以上にしかならないので、35.79分後にはオーバーフローの心配があります。
  • [以下のコードでの暗黙の前提]
    • この関数が十分な頻度で呼び出される。この十分な頻度というのは、clock()が振り切らない程度という意味です。
long long clkusec_c = 0LL;
clock_t clkusec_t0 = 0;

long long clkusec(void)
{
    clock_t t = clock(), dt = t - clkusec_t0;
    clkusec_t0 = t;
    clkusec_c += dt * (1000000 / CLOCKS_PER_SEC);
    return clkusec_c;
}

こめんと欄


コメントお名前NameLink

リロード   新規 編集 差分 添付   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS
Last-modified: 2019-02-08 (金) 19:09:01 (191d)