Linuxで時間を測定する-時間vsクロックvs getrusage vs clock_gettime vs gettimeofday vs timespec_get?


148

タイミング機能のうち、timeclock getrusageclock_gettimegettimeofdaytimespec_get、私は彼らが実装されている方法を明確に理解したいとどのような状況で、私はそれらを使用する必要があります知っているために、その戻り値がどのようなもの。

まず、壁時計の値を返す関数を、プロセスまたはスレッドの値を返す関数と比較して分類する必要があります。渡されたパラメーターに応じて、壁gettimeofday時計の値をclock_gettime返し、壁時計の値プロセスまたはスレッドの値を返しますClock。プロセス値getrusageclock返します。

次に、2番目の質問は、これらの関数の実装と、その結果としての正確さに関するものです。これらの関数が使用するハードウェアまたはソフトウェアのメカニズム。

getrusageカーネルティック(通常は1ミリ秒の長さ)のみを使用しているようです。その結果、ミリ秒よりも正確になることはありません。正しいですか?次に、getimeofday関数は利用可能な最も正確な基盤ハードウェアを使用しているようです。結果として、最近のハードウェアでは、その精度は通常マイクロ秒です(APIのためにそれ以上になることはありません)。何をclock、「近似」についてのmanページを話すが、それは何を意味するのでしょうか?何をclock_gettime、APIはナノ秒である、それは基礎となるハードウェアで許可されていれば、それはとても正確であることが可能だということを意味していますか?単調性はどうですか?

他の機能はありますか?

回答:


198

問題は、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ティック後に発生しますが、1 MHzクロックではそれほど長くありません)。man clockglibc 2.18以降clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)、Linuxで実装されていると述べています。
  • clock_gettime(CLOCK_MONOTONIC, ...)ナノ秒の分解能を提供し、単調です。「秒」と「ナノ秒」はそれぞれ32ビットカウンターに別々に格納されていると思います。したがって、何十年ものアップタイムが発生すると、ラップアラウンドが発生します。これは非常に優れた時計のように見えますが、残念ながらOS Xではまだ利用できません。POSIX7では、オプションの拡張機能として説明さCLOCK_MONOTONICれています
  • getrusage()私の状況にとって最良の選択であることが判明しました。ユーザー時間とシステム時間を別々に報告し、折り返しません。私のシステムの精度は1 µsですが、Linuxシステム(GCC 4.1.2を搭載したRed Hat 4.1.2-48)でもテストしたところ、精度は1 msしかありませんでした。
  • gettimeofday()(公称)µsの精度で実時間を返します。私のシステムでは、このクロックの精度はµsのようですが、「システムクロックの分解能はハードウェアに依存する」ため、これは保証されていません。POSIX.1-2008 はそれを述べています。「アプリケーションではclock_gettime()、廃止された関数の代わりに関数を使用する必要がある」ため、この関数gettimeofday()から離れてください。Linux x86およびそれをシステムコールとして実装します
  • mach_absolute_time()OS Xでの非常に高い解像度(ns)タイミングのオプションです。私のシステムでは、これは実際にns解像度を提供します。原則としてこのクロックはラップアラウンドしますが、64ビットの符号なし整数を使用してnsを格納しているため、ラップアラウンドは実際には問題になりません。移植性には疑問があります。
  • LinuxとOS Xの両方でns精度を取得するために、Linuxでコンパイルするときにclock_gettimeを使用するか、OS XでコンパイルするときにMachタイマーを使用するこのスニペットに基づいてハイブリッド関数を作成しました。

上記のすべては、特に指定のない限り、LinuxとOS Xの両方に存在します。上記の「私のシステム」は、MacPortsのGCC 4.7.2を搭載したOS X 10.8.3を実行しているAppleです。

最後に、上記のリンクに加えて参考にした参考文献のリストを次に示します。


更新:OS Xの場合clock_gettime、10.12(Sierra)の時点で実装されています。また、POSIXとBSDベースのプラットフォーム(OS Xなど)の両方がrusage.ru_utimestructフィールドを共有しています。


Mac OS Xにclock_gettimegettimeofday()clock_gettime()
はが

1
あなたは言及していませんtimes()(s付き)、問題1以来POSIXに存在しています。GNU/ Linuxに関して:clock(3)のマニュアルページによると、clock()glibc 2.17以前からはその上に実装されていましたが、改良されました精度。これは現在clock_gettime(CLOCK_PROCESS_CPUTIME_ID,...)、POSIXでも指定されていますがオプションです。
vinc17 2014

2
@starflyerクロックの精度は、クロックのポーリングにかかる​​時間によって部分的に制限されます。これは、クロックを呼び出して1マイクロ秒かかる場合、クロックが報告する時間は呼び出し側から見て1マイクロ秒「オフ」になるためです。つまり、高精度のクロックも低遅延でなければなりません。したがって、通常、あなたが話しているトレードオフはありません:最も安い時計も最も正確です。
ダグラスB.ステープル2015年

3
また、ほとんどの時計は、壁掛け時計と見なされても、夏時間/タイムゾーンを考慮しません。両方ともtimegettimeofday少なくとも今日では、エポックからの秒数(別名UNIXタイムスタンプ)を返します。これはタイムゾーン/ DSTに依存しません。うるう秒は別の話です...
ズラン

2
Androidユーザーの場合、CLOCK_MONOTONICを使用すると、アプリが時計とともに一時停止される可能性があるため、問題が発生する可能性があります。そのために、Androidはioctlを介してアクセス可能なANDROID_ALARM_ELAPSED_REALTIMEタイマーを追加しました。これらおよびその他の一時停止関連情報の一部については、こちらをご覧ください
Itay Bianco

17

C11 timespec_get

使用例:https : //stackoverflow.com/a/36095407/895245

返される可能な最大精度はナノ秒ですが、実際の精度は実装定義であり、それよりも小さくなる場合があります。

CPU使用率ではなく、経過時間を返します。

glibc 2.21はそれを下に実装し、以下にsysdeps/posix/timespec_get.c直接転送します。

clock_gettime (CLOCK_REALTIME, ts) < 0)

clock_gettimeおよびCLOCK_REALTIMEPOSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.htmlでありman clock_gettime、プログラムの実行中にシステム時間の設定を変更すると、この測定が不連続になる可能性があると述べています。

C ++ 11クロノ

私たちはそれを理解しているので、それらもカバーしましょう:http : //en.cppreference.com/w/cpp/chrono

GCC 5.3.0(C ++ stdlibはGCCソース内にあります):

  • high_resolution_clock のエイリアスです system_clock
  • system_clock 利用可能な次の最初のものに転送します。
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock 利用可能な次の最初のものに転送します。
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

質問:std :: system_clockとstd :: steady_clockの違いは?

CLOCK_REALTIMEvs CLOCK_MONOTONICCLOCK_REALTIMEとCLOCK_MONOTONICの違いは?


1
典型的な実装をわかりやすく説明する素晴らしい答えです。それは人々が本当に知る必要があることです。
Celess
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.