2012-09-12 350 views
114

其中計時功能,timeclockgetrusageclock_gettimegettimeofdaytimespec_get,我想清楚地瞭解它們是如何實現的,爲了知道在什麼情況下我必須使用他們什麼是他們的返回值。在Linux中測量時間 - 時間vs時鐘vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?

首先,我們需要進行分類的功能恢復掛鐘值比較返回處理功能或線程值gettimeofday返回掛鐘值,clock_gettime返回掛鐘值進程或線程值,具體取決於傳遞給它的參數Clockgetrusageclock返回過程值。

然後第二個問題關於這些功能的實現,因此,它們的準確性。這些功能使用哪種硬件或軟件機制。

看來getrusage只使用內核tick(通常爲1ms長),因此不能比ms更準確。這樣對嗎? 然後getimeofday函數似乎使用了最準確的底層硬件。因此,它的準確性通常是在最近的硬件上的微秒(不能因爲API)。 關於clock,手冊頁講的是「逼近」,這是什麼意思? clock_gettime怎麼樣,API是納秒,這是否意味着它可以如此精確,如果底層硬件允許它?單調性怎麼樣?

還有其他的功能嗎?

回答

150

問題是在C和C++中有幾種不同的時間函數可用,其中一些在實現之間的行爲上有所不同。還有很多半答案浮動。編譯時鐘函數列表及其屬性將正確回答問題。對於開始,讓我們問一下我們正在尋找的相關屬性。看看你的帖子,我建議:

  • 什麼時候測量的時鐘? (真實的,用戶的,系統的,還是希望不是掛鐘?)
  • 時鐘的精度是多少? (s,ms,μs還是更快?)
  • 時鐘迴繞了多少時間?還是有一些機制可以避免這種情況?
  • 時鐘是單調的,還是會隨着系統時間的變化而改變(通過NTP,時區,夏令時,用戶等)?
  • 上述內容在不同實現之間如何變化?
  • 特定功能是否過時,非標準等?

在開始列表之前,我想指出掛鐘時間很少是正確的使用時間,而它隨時區更改,夏時制時間更改或壁掛時鐘更改由NTP同步。如果您使用時間安排活動或基準測試,這些都不是很好。這只是真正的好名字,牆上的時鐘(或桌面)。

這裏是我到目前爲止已發現在Linux和OS X時鐘:

  • time()從OS返回掛鐘時間,精確的秒。
  • clock()似乎返回用戶和系統時間的總和。它出現在C89及更高版本中。有一次,這應該是CPU週期的時間,但現代標準like POSIX要求CLOCKS_PER_SEC爲1000000,最大可能的精度爲1微秒。我的系統精度確實是1μs。這個時鐘一旦回到頂部就會迴繞(這通常發生在〜2^32個滴答聲之後,對於1MHz時鐘來說這不是很長)。 man clock表示,自glibc 2.18以來,它在Linux中與clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)一起實現。
  • clock_gettime(CLOCK_MONOTONIC, ...)提供納秒分辨率,是單調的。我相信'秒'和'納秒'分別存儲在32位計數器中。因此,在正常運行數十年之後,任何繞回都會發生。這看起來像一個非常好的時鐘,但不幸的是它還不能在OS X上使用。POSIX 7 describes CLOCK_MONOTONIC as an optional extension
  • getrusage()原來是我的情況的最佳選擇。它分別報告用戶和系統時間,不會環繞。我的系統精度爲1微秒,但我也在Linux系統上進行了測試(Red Hat 4.1.2-48和GCC 4.1.2),精度僅爲1毫秒。
  • gettimeofday()返回(標稱)μs精度的掛鐘時間。在我的系統上,這個時鐘似乎具有μs精度,但這並不能保證,因爲"the resolution of the system clock is hardware dependent"。 POSIX.1-2008 says that。 「應用程序應該使用clock_gettime()函數而不是過時的gettimeofday()函數」,因此您應該遠離它。 Linux x86並實現它as a system call
  • mach_absolute_time()是OS X上的高分辨率(ns)定時選項。在我的系統上,這確實可以提供ns分辨率。原則上這個時鐘環繞,但是它使用一個64位的無符號整數來存儲ns,所以實際上這個環繞不應該是一個問題。可移植性值得懷疑。
  • I wrote a hybrid function基於this snippet使用clock_gettime在Linux上進行編譯時,編譯或OS X上的時候,爲了獲得在Linux納秒的精度和OS X.馬赫計時器

在上述所有的存在Linux和OS X都另有規定。上面的「我的系統」是一個運行OS X 10.8.3的Apple,MacPorts使用GCC 4.7.2。

最後,這裏是我除了發現有助於上面的鏈接引用的列表:


更新:對於OS X,clock_gettime自10.12(Sierra)起實施。另外,基於POSIX和BSD的平臺(如OS X)共享rusage.ru_utime結構體字段。在

+1

你現在有18個代表處點;-) –

+0

的Mac OS X沒有'clock_gettime',因此,使用的[ 'gettimeofday()'](http://www.songho.ca/misc/timer/timer.html)比'clock_gettime()'更具多功能性'' – bobobobo

+0

@bobobobo我同意OS X沒有clock_gettime() ),但gettimeofday()不幸地測量了掛鐘時間。我更新了我的帖子以提供此信息。如果ms精度足夠,那麼我推薦使用getrusage()作爲定時器的最佳時鐘。 –

12

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_gettimeCLOCK_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_clocksystem_clock的別名
  • system_clock轉發給以下第一個可用:
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock轉發到第一可用以下的:
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

在問:Difference between std::system_clock and std::steady_clock?

CLOCK_REALTIME VS CLOCK_MONOTONICDifference between CLOCK_REALTIME and CLOCK_MONOTONIC?

+1

謝謝你的補充。 –