いつもお世話になっている上川さんのLinux Kernel Watchより

http://www.atmarkit.co.jp/flinux/rensai/watch2006/watch06b.html

□sched_clock()による時間計測に注意

 短期間の処理に要した時間を計りたいという場合はよくあります。細かい時間で更新される時間カウンタとしては、sched_clock()という関数が使えます。例えば、以下のような用途が考えられるでしょう。

unsigned long long t0, t1, time_passed_ns;

t0 = sched_clock();
/* 時間を計りたい処理 */
t1 = sched_clock();

time_passed_ns = t1 - t0;

 実は、上のコードは間違っているとRussell Kingは指摘しました。例えば、x86ではTSCレジスタを利用しており、TSCレジスタの値は64bitです。sched_clock()はその値を加工してナノ秒に変換しているのですが、結果として精度は54bitになります。また、ARMではこれが32bitしかありません。これは何を意味するでしょうか?

 時間の経過とともに数字が増えるわけですが、ある時点で「0」に戻ります。それを64bitの変数の演算として見ると、突然長い時間が過ぎてしまったように見えます。この解決策の1つとして、彼は差分を計算する専用の関数sched_clock_diff()を定義することを提案しました。すると、そもそもsched_clock()をナノ秒で提供するように加工する必要がなくなります。また、SMPでは同期していない場合もあるので、TSCレジスタを汎用として利用するのは好ましくない、とNick Pigginがコメントしました。

 この状況はあまり良くないことではありますが、あまり文句も出ていないため「このコードを利用している部分はあまり存在しないのだね」という結論に達して、結局何も修正はなされていないようです。

 sched_clock()を利用する場合はご注意を。



64bit ulongの範囲だったらわざわざ新設せんでもtime_afterマクロで十分やんけ。と言ってみるテスト。

実際IA64のアーキ依存コードはタイマ割り込み周りでitcレジスタ(TSCレジスタみたいなもん。クロック毎にインクリメントされる64bitカウンタ)の比較をtime_afterでやってるぞ。

ポイントはjiffiesが所詮ただの64bit整数なので、jiffies用のマクロは全部途中で一周しちゃうような性質をもつ時間関係に使われている整数操作に汎用的に使えるってことだね。


うーん、小ネタだ。


あ、time_afterについては以下のブログが詳しいようです。

路地裏ソース解読研究室
時間は無限?(http://blog.miraclelinux.com/uraura/2006/06/post_4b60.html


ではでは



ノーブラ
そんなの必要ありません! ランキング!