問題は、C および C++ で使用できるいくつかの異なる時間関数があり、それらのいくつかは実装間で動作が異なることです。中途半端な回答もたくさん出回っています。クロック関数のリストとそのプロパティをコンパイルすると、質問に適切に答えることができます。まず、探している関連プロパティが何であるかを尋ねてみましょう。あなたの投稿を見て、次のことをお勧めします:
- 時計は何時を計っていますか? (本物、ユーザー、システム、または壁時計ではないことを願っています)
- 時計の精度は? (秒、ミリ秒、マイクロ秒、またはそれより速い?)
- 時計が一周するのにどれくらいの時間がかかりますか?または、これを回避するメカニズムはありますか?
- 時計は単調ですか?それとも、システム時刻の変更 (NTP、タイム ゾーン、夏時間、ユーザーなどによる) に伴って変化しますか?
- 上記は実装によってどのように異なりますか?
- 特定の機能は廃止されたり、非標準になったりしていませんか?
リストを開始する前に、タイムゾーンの変更、夏時間の変更、または壁時計が NTP によって同期されている場合は、壁時計の時間が使用するのに適切な時間になることはめったにないことを指摘したいと思います。イベントのスケジュール設定やパフォーマンスのベンチマークに時間を使用している場合、これらのことはどれも良いことではありません。名前が示すように、壁 (またはデスクトップ) の時計に最適です。
Linux と OS X の時計について、これまでにわかったことは次のとおりです。
time()
OS からのウォールクロック時間を秒単位の精度で返します。clock()
ユーザー時間とシステム時間の合計を返すようです。 C89 以降に存在します。かつて、これはサイクル単位の CPU 時間であると想定されていましたが、POSIX などの最新の標準では、CLOCKS_PER_SEC を 1000000 にする必要があり、可能な最大精度は 1 µs です。私のシステムの精度は確かに 1 µs です。このクロックは、上限に達するとラップアラウンドします (これは通常、1 MHz クロックとしてはそれほど長くない ~2^32 ティック後に発生します)。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 マイクロ秒ですが、Linux システム (GCC 4.1.2 を使用する Red Hat 4.1.2-48) でもテストしたところ、精度はわずか 1 ミリ秒でした。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 です。
最後に、上記のリンクに加えて、私が参考にした参考文献のリストを以下に示します:
- 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
を共有しています。 構造体フィールド。
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_REALTIME
POSIX 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_REALTIME
vs CLOCK_MONOTONIC
:CLOCK_REALTIME と CLOCK_MONOTONIC の違いは?