操作系統中的主存儲器&高速緩存

瞭解操作系統的存儲管理

存儲管理是操作系統的重要組成部分,它負責管理計算機系統中的主存儲器。

任何程序(代碼)及數據在執行前必須進入主存空間,因此存儲管理的優劣直接影響系統的性能,主存儲空間一般分爲兩部分:一部分是系統區,存放操作系統的核心程序以及標準子程序等;另一部分是用戶區,存放用戶的程序和數據等,供當前正在執行的程序使用。我們所關注的存儲管理就是用戶區的管理,操作系統的任務之一就是要儘可能方便用戶使用以及提高主存儲器的利用效率;而且,有效的存儲管理也是多道程序設計系統的關鍵支撐,存儲管理主要有如下功能

  • 主存儲空間的分配和回收

  • 地址轉換和存儲保護

  • 主存空間的共享

  • 主存空間的擴充

操作系統中存儲器的層次

介於處理器和內存二者之間的緩存有兩個天然衝突的性能指標:速度和容積,這個矛盾也是引入多級緩存的主要原因。

操作系統中的存儲一般分爲六層結構,寄存器,高速緩存(CPU Cache),主存儲器,磁盤緩存,固定磁盤,可移動存儲等;如下圖所示,越往上,存儲介質的訪問速度越快,但是內存也越小;

其中,寄存器、高速緩存以及主存儲器和磁盤緩存都屬於操作系統存儲管理的範圍,掉電之後它們的信息不再存在;而固定磁盤管理和可移動存儲介質屬於設備管理的管轄範疇,它們存儲的信息將被長期保存。

可執行的程序必須被保存在計算機主存中,但是CPU訪問主存的時間要遠大於處理時間,所以寄存器和高速緩存被引入用於加快指令的執行;

高速緩存

高速緩存的容量比寄存器大,而訪問速度比主存要快,使用它存放主存中一些經常訪問的信息可以大幅度提高程序執行速度;比如主存訪問速度1微秒,高速緩存爲0.1微秒,如果訪問信息在高速緩存中的機率爲50,那麼存儲器的訪問速度就可以提高到0.55微秒。因此,提高訪問信息在CPU Cache中的命中是一個非常重要的事情,比如Unity的ECS、DOTS架構等就是通過合理分配存儲空間來提高Cache的命中率從而提高性能。

一般來說程序的處理流程爲,數據信息存放在主存中,每當使用它時,就會將其賦值到一個訪問速度很快的cache中,當CPU訪問一組特定信息時,首先,檢查是否在cache中,如果存在,直接取用;否則,就從主存中讀信息,通常認爲這批信息被再次用到的概率很高,所以同時還把主存讀出的信息複製到cache中。

在CPU的內部寄存器和主存之間建立了一個cache,而由程序員或編譯系統實現寄存器的分配或替換算法,以決定信息是保存在寄存器還是在主存。有一些cache是通過硬件實現的,如大多數計算機有指令cache,用來暫存下一條欲執行的指令,如果沒有指令cache,CPU將會空等若干個週期,直到下一條指令從主存中取出。多數計算機系統的存儲層次中設置了一個或多個高速數據cache,可見cache是解決主存速度與CPU速度不相匹配的一種部件。

Cache的設計

由於高速cache的容量有限(速度小於25ns,容量有128k和256k),所以,cache的管理是一個重要的設計問題,仔細確定其大小和替換策略,能夠做到80%-99%的所需信息在cache中找到。主存也可以看作是輔存的cache,因爲輔存中的數據必須複製到主存方能使用;反之,數據也必須先存在主存中,才能輸出到輔存。一個文件的數據可能出現在存儲器層次的不同級別中,例如,操作系統可在主存中維護一個文件數據的cache。

高速緩存之所以有效,是因爲程序運行時對內存的訪問呈現局部性特徵,這種局部性既包括空間局部性也包括時間局部性。所以,有效利用這種局部性,緩存可以達到極高的命中率。而在處理器看來,cache對程序開發者而言是透明的,因此開發者無法直接干預對緩存的操作,但是可以根據緩存的特點對代碼進行特定優化,從而更好利用緩存。

Cache的存儲結構

在結構上,一個直接映射緩存由若干緩存塊構成。每個緩存塊存儲具有連續內存地址的若干個存儲單元,在32位中每個存儲單元佔雙字,即四個字節,每個雙字具有唯一的塊內偏移量。

每一個緩存塊有一個索引,它一般是內存地址的低端部分,但不含塊內偏移和字節偏移所佔的最低若干位,一個數據總量爲4KB、緩存塊大小爲16B的直接映射緩存一共有256個緩存塊,其索引範圍爲0到255,使用一個簡單的移位函數就可以得到任意內存地址對應的緩存塊的索引。由於這種是多對一映射,必須在存儲一段數據的同時標識出這些數據在內存中的確切位置,所以每個緩存塊都配有一個tag,拼接標籤值和此緩存塊的索引,即可求得緩存塊的內存地址,再通過塊內偏移可以算出任意一塊數據的內存地址。

因此,在緩存大小不變的情況下,緩存塊的大小和緩存塊的數量總是呈反比;

另外,如下圖所示,緩存塊中還有若干標誌位,包括有效位、髒位、使用位等,這些在保證正確性、排除衝突、優化性能等方面起重要作用。

Cache後數據的一致性

在層次式存儲結構中,相同的數據可能出現在不同層次上。例如,考慮對文件B中的一個整數A做加1操作,假如文件B儲存在磁盤上,首先,發出I/O指令,它把A所在的盤塊讀到主存中,再做加法操作。跟着這個操作,可能把A的一個副本複製到cache,而A的另一個副本複製到CPU寄存器。因此,A的副本出現在層次的若干地方,當加1操作在CPU寄存器執行之後,在存儲器各層次中,A的值是不同的,僅當A的新值被寫回磁盤之後,A的值纔會變成相同。

在多CPU環境中,情況變得較爲複雜,除了維護CPU寄存器外,CPU還包含一個局部數據cache,於是,A的副本可能同時出現在若干個cache中,所有的CPU都併發地執行,對A值在某個cache中的修改,立即會影響到A所在的所有其它cache,這個問題稱作緩衝一致性問題。

參考:與程序員相關的CPU緩存知識

緩存數據的置換策略

當一個組的全部緩存塊都被佔滿後,如果再次發生緩存失效,就必須選擇一個緩存塊來替換掉,存在多種策略決定哪個塊被替換。最理想的替換塊應該是距離下一次被訪問最晚的那個,但這個是無法真正實現的,可它的方向是正確的。比如先進先出FIFO算法,替換掉進入組內時間最長的緩存塊;最久未使用LRU算法則跟蹤各個緩存塊的使用情況,並根據統計比較出哪個塊已經最長時間未被訪問,這兩種算法的時間代價比較高,一個替代的算法是NMRU非最近使用算法,這個算法僅僅記錄哪一個緩存虧啊是最近被使用的,在替換時,會隨機替換掉任何一個其它的塊。

緩存數據的寫操作

爲了和下級存儲保持數據一致性,就必須把數據更新適時傳播下去,一般有兩種回寫策略:寫回和寫通。

寫回:僅當一個緩存塊需要被替換回內存時,纔將其內容寫入內存。如果緩存命中,則不需要更新內存。爲了減少內存的寫操作,緩存塊通常還設有一個髒位,用於標識該塊在被載入以後是否發生過更新,如果一個緩存塊在被置換回內存之前從未被寫入過,則可以免去寫操作。寫回的好處是節省了大量的寫操作,對每個數據塊內不同單元的更新僅需要一次寫操作就可以完成。

寫通:每當緩存接收到寫數據指令,都直接將數據寫回到內存,如果數據地址在緩存中,也必須同時更新緩存。寫通較容易實現,並且能更簡單地維持數據一致性。

地址轉換與存儲保護

開發者通過高級編程語言編寫的源程序是不能被計算機直接執行的,需要通過編譯程序或彙編程序編譯或彙編獲得目標程序。目標程序的地址不是內存的實際地址,把用戶目標程序使用的地址單元稱爲邏輯地址,一個用戶作業的目標程序的邏輯地址集合稱爲該作業的邏輯地址空間。

作業的邏輯地址空間可以是一維的,邏輯地址限制在從0開始的地址空間內;也可以是二維的,這時整個用戶作業被分爲若干段,每段有不同的段號,段內地址從0開始。當程序運行時,它將被裝入主存地址空間的某些部分,此時程序和數據的實際地址一般不可能同原來的邏輯地址一致,把主存中的實際存儲單元稱爲物理地址(絕對地址),物理地址的總體相應構成了用戶程序實際運行的物理地址空間,這個空間是由存儲器地址總線掃描出來的空間,其大小取決於實際安裝的主存容量。

爲了保證程序的正確運行,必須把程序和數據的邏輯地址轉換爲物理地址,這一過程稱爲地址轉換或重定位。地址轉換有兩種方式,一種是作業裝入時由作業裝入程序實現地址轉換,這種是靜態重定位,要求目標程序使用相對地址,地址變換在作業執行前完成所有地址轉換工作;第二種方式,在程序執行過程中,CPU訪問程序和數據之前實現地址轉換,這種稱謂動態重定位。在多道程序設計系統中,可用的主存空間通常是被許多進程共享的,而且必須要允許程序因對換或者空區收集而移動,這些問題都需要程序的動態重定位,而動態重定位則必須藉助於硬件的地址轉換來實現。

存儲保護

在多道程序中,操作系統程序和各個用戶程序在主存中各有自己的存儲區域,各道程序只能訪問自己的工作區而不能相互干擾,因此,操作系統必須對主存中的程序和數據進行保護,以免其他程序有意或無意的破壞,這個工作就是存儲保護,它也需要藉助相應的硬件來實現。

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