[解決済み] Linux で時間を計測する - time vs clock vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?
質問
タイミング機能のうち
time
,
clock
getrusage
,
clock_gettime
,
gettimeofday
と
timespec_get
どのような状況でそれらを使用しなければならないかを知るために、それらがどのように実装され、どのような戻り値であるかを明確に理解したいのです。
まず、以下のような関数を分類する必要があります。
壁掛け時計の値
を返す関数と比較します。
プロセスまたはスレッドの値
.
gettimeofday
は壁掛け時計の値を返します。
clock_gettime
壁掛け時計の値を返す
または
プロセスまたはスレッドの値は
Clock
パラメータに渡されます。
getrusage
と
clock
は処理値を返します。
次に、これらの関数の実装と、その結果としての精度に関する質問です。これらの関数は、どのようなハードウェアまたはソフトウェアのメカニズムを使用しているのでしょうか。
と思われます。
getrusage
はカーネルティック(通常1msの長さ)のみを使用し、結果としてmsより正確な値を得ることはできません。これは正しいのでしょうか?
では
getimeofday
関数は、利用可能な最も正確なハードウェアを使用しているようです。その結果、最近のハードウェアでは、その精度は通常マイクロ秒(APIの関係でそれ以上にはならない)です。
では
clock
manページには「近似値」と書かれていますが、どういう意味ですか?
また
clock_gettime
APIはナノ秒単位ですが、ハードウェアが許せば、これだけの精度が出せるということでしょうか?単調性はどうなのでしょうか?
その他の機能はありますか?
解決方法は?
問題は、CやC++で利用できる時間関数は数種類あり、その中には実装によって動作が異なるものがあることです。 また、中途半端な答えが多く出回っている。 時計関数の一覧とそのプロパティをまとめれば、この問題に適切に答えられるだろう。 手始めに、私たちが求めているのはどのような特性なのかを聞いてみましょう。あなたの投稿を見ると、私は提案します。
- 時計が計測している時間は何時ですか?(実時間、ユーザー時間、システム時間、あるいは壁掛け時計など?)
- クロックの精度は?(s、ms、µs、またはそれ以上?)
- クロックは何秒後にラップアラウンドしますか?または、それを避けるための何らかのメカニズムがあるのでしょうか?
- 時計は単調ですか、それともシステム時刻の変更(NTP、タイムゾーン、サマータイム、ユーザーによるものなど)に応じて変更されますか?
- 上記は実装によってどのように違うのですか?
- 特定の機能は廃止されているか、非標準であるか、など。
リストを始める前に、壁掛け時計の時刻は、タイムゾーンの変更、サマータイムの変更、壁掛け時計がNTPで同期されている場合などに変化するのに対し、正しい時刻であることはほとんどないことを指摘しておきたいと思います。 イベントのスケジュールやパフォーマンスのベンチマークに時間を使用する場合は、これらのいずれもが良いことではありません。本当に良いのは、その名の通り、壁(またはデスクトップ)の時計としてだけなのです。
LinuxとOS Xの時計について、これまで私が見つけたものは以下の通りです。
-
time()
はOSの壁時計の時刻を秒単位で返します。 -
clock()
は、ユーザ時刻とシステム時刻の合計を返すようです。C89以降に存在する。一時期、これはCPU時間をサイクル単位で表すとされていましたが、現代の標準では POSIXのように CLOCKS_PER_SECは1000000であることが要求されており、最大で1μsの精度が得られます。私のシステムでの精度は確かに1µsです。 このクロックはトップアウトするとラップアラウンドします(これは通常 ~2^32 ticks 後に起こりますが、1 MHz のクロックとしてはそれほど長くはありません)。man clock
によると、glibc 2.18以降で実装されているのはclock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)
を Linux で使用することができます。 -
clock_gettime(CLOCK_MONOTONIC, ...)
は、ナノ秒の分解能を持ち、モノトニックである。秒」と「ナノ秒」は別々に、それぞれ32ビットのカウンタに格納されていると思います。 したがって、何十年も稼働させれば、ラップアラウンドが発生するでしょう。これは非常に良い時計のように見えるが、残念ながらOS Xではまだ利用できない。POSIX 7 を記述しています。CLOCK_MONOTONIC
オプションの拡張子として . -
getrusage()
が私の状況にはベストな選択であることがわかりました。これはユーザータイムとシステムタイムを別々に報告し、折り返しもしません。私のシステムでの精度は1μsですが、Linuxシステム(Red Hat 4.1.2-48 with GCC 4.1.2)でもテストしましたが、そこでの精度はわずか1msでした。 -
gettimeofday()
は壁掛け時計の時刻を(公称)μs精度で返します。私のシステムでは、この時計はµsの精度を持っているように見えますが、これは保証されていません。 システムクロックの分解能はハードウェアに依存します。 . POSIX.1-2008 には、次のように書かれています。 アプリケーションはclock_gettime()
関数の代わりに、旧式のgettimeofday()
function"なので、手を出さない方がいいでしょう。Linux x86で実装している システムコールとして . -
mach_absolute_time()
は、OS Xで超高解像度(ns)タイミングを実現するためのオプションです。私のシステムでは、これは確かにnsの分解能を与えています。原理的にはこのクロックは折り返しになりますが、64ビットの符号なし整数を使用してnsを格納しているので、実際には折り返しは問題にならないはずです。移植性には疑問があります。 - ハイブリッド関数を書いてみた をベースに このスニペット は、Linux と OS X の両方で ns 精度を得るために、Linux でコンパイルした場合は clock_gettime を、OS X でコンパイルした場合は Mach timer を使用します。
上記は、特に指定がない限り、すべてLinuxとOS Xの両方に存在します。上記における "私のシステム"は、OS X 10.8.3 と MacPortsからのGCC 4.7.2 を実行しているAppleです。
最後に、上記のリンクの他に参考になった文献を紹介します。
- http://blog.habets.pp.se/2010/09/gettimeofday-should-never-be-used-to-measure-time
- LinuxでC言語プログラムの実際の実行時間を測定する方法は?
- http://digitalsandwich.com/archives/27-benchmarking-misconceptions-microtime-vs-getrusage.html
- http://www.unix.com/hp-ux/38937-getrusage.html
更新情報
: OS X用です。
clock_gettime
は、10.12(Sierra)より実装されました。また、POSIX系とBSD系(OS Xなど)のプラットフォームでは、共通して
rusage.ru_utime
構造体フィールド
関連
-
error: '.' トークンの前にunqualified-idを指定する必要があります。
-
[解決済み] c または c++ 用のシンプルな 2 次元クロスプラットフォームグラフィックスライブラリ?[クローズド]
-
[解決済み] char *とchar[]の違い [重複]
-
[解決済み] "static const" vs "#define" vs "enum"
-
[解決済み] LinuxのシェルスクリプトでYes/No/Cancelの入力を促すにはどうしたらいいですか?
-
[解決済み] Cコードの単体テスト【終了しました
-
[解決済み] Linux, Bashで、現在の時刻をEpochからの秒数で取得する。
-
[解決済み] C言語でランダムなint型を生成するには?
-
[解決済み] Windowsのコマンドラインでコマンドの実行時間を測定するにはどうすればよいですか?
-
[解決済み] FortranはC言語よりも重い計算を最適化しやすいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
構造体の配列--[エラー] '['トークンの前に一次式があることが予想される
-
ポインタ定数および定数ポインタ
-
警告:符号付き整数式と符号なし整数式の比較 [-Wsign-compare]
-
[解決済み] ANSI Cでミリ秒単位で時間を計るには?
-
[解決済み] 初期化でポインタ対象の型から修飾語を捨てる
-
[解決済み] 配列の場合、なぜ a[5] == 5[a] になるのでしょうか?
-
[解決済み] C言語で配列のサイズを決定するにはどうすればよいですか?
-
[解決済み] C言語で関数をパラメータとして渡すにはどうすればよいですか?
-
[解決済み] printfにおけるdoubleの正しい書式指定子
-
[解決済み】CLOCK_REALTIMEとCLOCK_MONOTONICの違い?