Linux 時間

    對 Linux 時間的理解一直很零散、片面,這次下決心繫統的整理下。

    在 x86 體系結構上,總體來說,存在兩種與時間相關的硬件:時鐘和定時器。前者相當於手錶,記錄絕對時間,後者相當於秒錶,記錄相對時間。但其實兩者都可歸結爲定時器。以下就分別說開來。

    先說簡單的吧:時鐘,也稱爲實時時鐘,Real Time Clock(RTC)。在所有的 PC 上都存在,在硬件上,它獨立於 CPU 和其它所有芯片,是和 CMOS 集成在一起的,依靠主板上的微型電池供電。這就是爲什麼系統關機後,時間也不會受到影響。RTC 能在 IRQ8 上發出週期性的中斷,頻率在 2-8192HZ 之間。此外,就像手錶也可以用來記時一樣,RTC 也支持對其進行編程,以使當 RTC 到達某個特定的值時激活 IRQ8 總線,即把它當成秒錶來使用。當然,Linux 只利用它來獲取時間和日期的,在系統啓動的時候,內核通過讀取 RTC 來初始化 xtime 變量,再結合系統啓動時間(用啥來表示待會會提到),就能計算出當前時間。

    其實對於 RTC 的理解,以上就足夠了。後續待補充的,是 Linux 內核初始化及更新 xtime 的具體實現。

    接下來就談談相對複雜的定時器。

    跟時鐘不同,定時器關注的是相對時間。每當設定的時間到了,定時器就會跳出來提醒你,就如同每天早上叫你起牀的鬧鐘。有兩點,第一,設定的時間到了,也即週期性的時間,是如何實現的?第二,如何跳出來?

    在 x86 體系結構中有多種定時器:

    1. TSC(Time Stamp Counter)

    利用 64 位的時間戳計數器寄存器來實現,接收外部振盪器的時鐘信號,在每個時鐘信號到來時加 1。所謂的時鐘信號,是指有固定週期並與運行無關的信號量,對應於 CPU 的主頻。例如當 CPU 的主頻爲 1GHz,那麼 TSC 每納秒增加 1 次。

    可以看到,該計數器的增長是非常快的,那是否會產生溢出呢?算算便知:假設 CPU 主頻爲 10G,2^63/10^10,結果約爲 29 年,足夠用了。

    利用該寄存器,可以獲得非常精確的時間測量。事實上,Linux 也是據此來確定 CPU 的主頻。calibrate_tsc() 函數通過計算一個大約在 5ms 的時間間隔內所產生的時鐘信號的個數,來算出 CPU 的實際頻率。因爲編譯內核時並不會聲明該頻率,所以同一內核映象可以運行在任何時鐘頻率的 CPU 上。

    通過彙編指令 rdtsc 可以讀取該寄存器的值。所謂性能應該是計算出來的而不是測試出來的,該指令提供了一種計算的途徑,後面會專門介紹。

    2. PIT(Programmable Interval Timer)

    每個 IBM 兼容 PC 都至少包含一個 PIT。如果覺得很枯燥、記憶起來有點困難的話,那就記住這個 Programmable,可編程。這個很關鍵。誰會去對它編程呢?當然是偉大的 Linux 內核了。好,前戲談完,即將正式進入主題了。

    首先,既然是間隔定時器,那間隔是多少?如何確定下來的呢?答案叫 HZ,也叫 tick rate。Linux 內核依據這個值,對該定時器編程。在 Linux 2.5 之後,HZ 從 100 調整到了 1000。這個 1/HZ 的間隔也成爲 tick,翻譯成中文叫節拍或者滴答。說到這裏,你會不會有困惑:1/1000 秒也才 1ms,這個精度也太差了吧,像 us、ns 之類的精度,依靠這個定時器,怎麼能達到呢。這個問題很好,但我們暫時先不回答。

    其次,如何通知定時的時間已到。估計你也猜到了,答案是中斷。PIT 使用的中斷號是 IRQ0。

    有了以上兩點,我們就能知道,PIT 永遠以內核確定的固定頻率,不停的發出中斷。所謂的系統定時器,指的就是 PIT。而這個中斷,就是大名鼎鼎的時鐘中斷,看看中斷裏都幹了啥事情,就知道其地位了:

    1. 更新系統運行時間

    2. 更新實際時間

    3. 檢查當前進程是否已經耗盡了時間片,如果是,則重新調度

    4. 在 smp 系統上,均衡調度程序中各處理器上的運行隊列

    是不是都是些高大上的事情?

    對於 HZ 應該設置成多少的問題,顯然,越高越精確,但是系統的負載也越重。結論是:

    1. 沒有證據顯示,對系統中所有程序而言,頻率爲 1000 比頻率爲 100 更合適;

    2. 在現代計算機系統上,時鐘頻率爲 1000HZ 不會導致難以接受的負擔,並且不會對系統性能造成較大的影響。

    這些說完後,就可以引出 jiffies 這個內核中的全局變量了。jiffies 記錄的是系統啓動以來產生的節拍總數,也即時鐘中斷的總數。因爲一秒鐘內時鐘中斷的次數等於 HZ,所以 jiffies 一秒內的增加值也就爲 HZ。所以,有以下轉換公式:

    秒 = jiffies / HZ

    或者:

    jiffies = 秒 * HZ

    話說,除了瞭解概念之外,還必須理解、必須使用過,方能真正掌握。對於 PIT、HZ、tick 等等,應該是理解了,但是 jiffies 是用來幹嘛的、什麼地方能用到呢?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章