虛擬存儲概念
虛擬存儲
- 概念:基於非連續存儲內存分配的基礎上,可以把一部分內訓放在外存裏
- 需求
- 計算機系統時常出現內存空間不夠用
- 覆蓋( overlay )
應用程序手動把需要的指令和數據保存在內存中 - 交換( swapping )
操作系統自動把暫時不能執行的程序保存到外存中 - 虛擬存儲
在有限容量的內存中,以頁爲單位自動裝入更多更大的程序
- 覆蓋( overlay )
- 計算機系統時常出現內存空間不夠用
覆蓋技術
- 目標:在較小的可用內存中運行較大的程序
- 方法:依據程序邏輯結構,將程序劃分爲若干功能相對獨立的模塊;將不會同時執行的模塊共享同一塊內存區域
- 必要部分(常用功能)的代碼和數據常駐內存
- 可選部分(不常用功能)放在其他程序模塊中,只在要用到時裝入內存
- 不存在調用關係的模塊可相互覆蓋,共用同一內存區域
- 不足
- 增加編程困難
- 需程序員劃分功能模塊,並確定模塊間的覆蓋關係
- 增加了編程的複雜度
- 增加執行時間
- 從外存裝入覆蓋模塊
- 時間換空間
- 增加編程困難
交換技術
- 目標:增加正在運行或需要運行的程序的內存
- 實現方法
- 可將暫時不能運行的程序放到外存
- 換入換出的基本單位
- 整個進程的地址空間
- 換出( swap out )
- 把一個進程的整個地址空間保存到外存
- 換入( swap in )
- 將外存中某進程的地址空間讀入到內存
- 交換技術面臨的問題
- 交換時機:何時需要發生交換?
- 只當內存空間不夠或有不夠的可能時換出
- 交換區大小
- 存放所有用戶進程的所有內存映像的拷貝
- 程序換入時的重定向:換出後再換入時要放在原處嗎?
- 採用動態地址映射的方法
- 交換時機:何時需要發生交換?
覆蓋和交換的比較
- 覆蓋
- 只能發生在沒有調用關係的模塊間
- 程序員須給出模塊間的邏輯覆蓋結構
- 發生在運行程序的內部模塊間
- 交換
- 以進程爲單位
- 不需要模塊間的邏輯覆蓋結構
- 發生在內存進程間
虛擬存儲技術的目標
- 只把部分程序放到內存中,從而運行比物理內存大的程序
- 由操作系統自動完成,無需程序員的干涉
- 實現進程在內存與外存之間的交換,從而獲得更多的空閒內存空間
- 在內存與外存之間只交換進程的部分內容
局部性原理( principle of locality )
- 程序在執行過程中的一個較短時期,所執行的指令地址和指令的操作數地址,分別侷限於一定區域。
- 時間局部性
- 一條指令的一次執行和下次執行,一個數據的一次訪問和下次訪問都集中在一個較短時期內
- 空間局部性
- 當前指令和鄰近的幾條指令,當前訪問的數據和鄰近的幾個數據都集中在一個較小區域內
- 分支局部性
- 一條跳轉指令的兩次執行,很可能跳到相同的內存位置
- 局部性原理的意義
- 從理論上來說,虛擬存儲技術是能夠實現的,而且可取得滿意的效果
- 時間局部性
虛擬存儲的基本概念
- 思路:將不常用的部分內存塊暫存到外存
- 原理
- 裝載程序時
- 只將當前指令執行需要的部分頁面或段裝入內存
- 指令執行中需要的指令或數據不在內存(稱爲缺頁或缺段)時
- 處理器通知操作系統將相應的頁面或段調入內存
- 操作系統將內存中暫時不用的頁面或段保存到外存
- 裝載程序時
- 實現方式
- 虛擬頁式存儲
- 虛擬段式存儲
- 基本特徵
- 不連續性
- 物理內存分配非連續
- 虛擬地址空間使用非連續
- 大用戶空間
- 提供給用戶的虛擬內存可大於實際的物理內存
- 部分交換
- 虛擬存儲只對部分虛擬地址空間進行調入和調出
- 不連續性
- 支持技術
- 硬件:頁式或段式存儲中的地址轉換機制
- 操作系統:管理內存和外存間頁面或段的換入和換出
虛擬頁式存儲管理
- 在頁式存儲管理的基礎上,增加請求調頁和頁面置換
- 思路
- 當用戶程序要裝載到內存運行時,只裝入部分頁面,就啓動程序運行
- 進程在運行中發現有需要的代碼或數據不在內存時,則向系統發出缺頁異常請求
- 操作系統在處理缺頁異常時,將外存中相應的頁面調入內存,使得進程能繼續運行
- 虛擬頁式存儲中的頁表項結構
- 駐留位:表示該頁是否在內存
- 1表示該頁位於內存中,該頁表項是有效的,可以使用
- 0表示該頁當前在外存中,訪問該頁表項將導致缺頁異常
- 修改位:表示在內存中的該頁是否被修改過
- 回收該物理頁面時,據此判斷是否要把它的內容寫回外存
- 訪問位:表示該頁面是否被訪問過(讀或寫)
- 用於頁面置換算法
- 保護位:表示該頁的允許訪問方式
- 只讀,可寫,可執行等
- 駐留位:表示該頁是否在內存
- 虛擬頁式存儲中的外存管理
- 在何處保存未被映射的頁?
- 應能方便地找到在外存中的頁面內容
- 交換空間(磁盤或者文件)
- 採用特殊格式存儲未被映射的頁面
- 虛擬頁式存儲中的外存選擇
- 代碼段:可執行二進制文件
- 動態加載的共享庫程序段:動態調用的庫文件
- 其他段:交換空間
- 在何處保存未被映射的頁?
- 虛擬頁式存儲管理的性能
- 有效存儲訪問時間( effective memory access time EAT )
- EAT = 訪存時間 * (1-p) + 缺頁異常處理時間 * 缺頁率 p
- 例子:
- 訪存時間:10 ns;磁盤訪問時間:5 ms;缺頁率 p;頁修改概率 q;
- EAT = 10(1-p) + 5,000,000p(1+q)
- 有效存儲訪問時間( effective memory access time EAT )
缺頁異常(缺頁中斷)的處理流程
- 在內存中有空閒物理頁面時,分配一物理頁幀 f,轉第 5 步
- 依據頁面置換算法選擇將被替換的物理頁幀 f,對應邏輯頁 q
- 如 q 被修改過,則把它寫回外存
- 修改 q 的頁表項中駐留位置爲 0
- 將需要訪問的頁 p 裝入到物理頁面 f
- 重新執行產生缺頁的指令
頁面置換算法
置換算法的功能和目標
- 功能
- 當出現缺頁異常,需調入新頁面而內存已滿時,置換算法選擇被置換的物理頁面
- 設計目標
- 儘可能減少頁面的調入調出次數
- 把未來不再訪問或短期內不訪問的頁面調出
- 頁面鎖定( frame locking )
- 描述必須常駐內存的邏輯頁面
- 操作系統的關鍵部分
- 要求響應速度的代碼和數據
- 頁表中的鎖定標誌位( lock bit )
- 置換算法的評價方法
- 記錄進程訪問內存的頁面軌跡
- 舉例:虛擬地址訪問用(頁號,位移)表示
(3,0), (1,9), (4,1), (2,1), (5,3), (2,0), (1,9), (2,4), (3,1), (4,8) - 對應的頁面軌跡
3,1,4,2,5,2,1,2,3,4
替換c,a,d,b,e,b,a,b,c,d
- 舉例:虛擬地址訪問用(頁號,位移)表示
- 評價方法
- 模擬頁面置換行爲,記錄產生缺頁的次數
- 更少的缺頁,更好的性能
- 記錄進程訪問內存的頁面軌跡
- 頁面置換算法分類
- 局部頁面置換算法
- 置換頁面的選擇範圍僅限於當前進程佔用的物理頁面內
- 最優算法,先進先出算法,最近最久未使用算法
- 時鐘算法,最不常用算法
- 全局頁面置換算法
- 置換頁面的選擇範圍是所有可換出的物理頁面
- 工作集算法,缺頁率算法
- 局部頁面置換算法
最優頁面置換算法( OPT,optional )
- 基本思路:置換在未來最長時間不訪問的頁面
- 算法實現
- 缺頁時,計算內存中每個邏輯頁面的下一次訪問時間
- 選擇未來最長時間不訪問的頁面
- 算法特徵
- 缺頁最少,是理想情況
- 實際系統中無法實現
- 無法預知每個頁面在下次訪問前的等待時間
- 作爲置換算法的性能評價依據
- 在模擬器上運行某個程序,並記錄每一次的頁面訪問情況
- 第二遍運行時使用最優算法
先進先出算法( First-In First-Out,FIFO )
- 思路:選擇在內存駐留時間最長的頁面進行置換
- 實現
- 維護一個記錄所有位於內存中的邏輯頁面鏈表
- 鏈表元素按駐留內存的時間排序,鏈首最長,鏈尾最短
- 出現缺頁時,選擇鏈首頁面進行置換,新頁面加到鏈尾
- 特徵
- 實現簡單
- 性能較差,調出的頁面可能是進場訪問的
- 進程分配物理頁面數增加時,缺頁並不一定減少(Belady現象)
- 很少單獨使用
最近最久未使用算法( Least Recently Used,LRU )
- 思路
- 選擇最長時間沒有被引用的頁面進行置換
- 如某些頁面長時間未被訪問,則它們在將來還可能會長時間不會訪問
- 實現
- 缺頁時,計算內存中每個邏輯頁面的上一次訪問時間
- 選擇上一次使用到當前時間最長的頁面
- 特徵
- 最優置換算法的一種近似
- LRU 算法的可能實現方法
- 頁面鏈表
- 系統維護一個按最近一次訪問時間排序的頁面鏈表
- 鏈表首節點是最近剛剛使用過的頁面
- 鏈表尾節點是最久未使用的頁面
- 訪問內存時,找到相應頁面,並把它移到鏈表之首
- 缺頁時,置換鏈表尾節點的頁面
- 系統維護一個按最近一次訪問時間排序的頁面鏈表
- 活動頁面棧
- 訪問頁面時,將此頁號壓入棧頂,並棧內相同的頁號抽出
- 缺頁時,置換棧底的頁面
- LRU 算法特徵:開銷比較大
- 頁面鏈表
時鐘置換算法( Clock )
- 思路:僅對頁面的訪問情況進行大致統計
- 數據結構
- 在頁表項中增加訪問位,描述頁面在過去一段時間的內訪問情況
- 各頁面組織成環型鏈表
- 指針指向最先調入的頁面
- 算法
- 訪問頁面時,在頁表項記錄頁面訪問情況
- 缺頁時,從指針處開始順序查找未被訪問的頁面進行置換
- 特徵:時鐘算法是 LRU 和 FIFO 的折中
- 實現
- 頁面裝入內存時,訪問位初始化爲0
- 訪問頁面(讀/寫)時,訪問位置1
- 缺頁時,從指針當前位置順序檢查環形鏈表
- 訪問位爲0,則置換該頁
- 訪問位爲1,則訪問位置0,並指針移動到下一個頁面,直到找到可置換的頁面
- 改進的 Clock 算法
- 思路:減少修改頁的缺頁處理開銷
- 算法
- 在頁面中增加修改位,並在訪問時進行相應修改
- 缺頁時,修改頁面標誌位,以跳過有修改的頁面
最不常用算法( Least Frequently Used,LFU )
- 思路:缺頁時,置換訪問次數最少的頁面
- 實現
- 每個頁面設置一個訪問計數
- 訪問頁面時,訪問計數加1
- 缺頁時,置換計數最小的頁面
- 特徵
- 算法開銷大
- 開始時頻繁使用,但以後不使用的頁面很難置換
- 解決方法:計數定期右移
- LRU 和 LFU 的區別
- LRU 關注多久未訪問,時間越短越好
- LFU 關注訪問次數,次數越多越好
Belady現象
- 現象:採用 FIFO 等算法時,可能出現分配的物理頁面數增加,缺頁次數反而升高的異常現象
- 原因
- FIFO 算法的置換特徵與進程訪問內存的動態特徵矛盾
- 被它置換出去的頁面並不一定是進程近期不會訪問的
- FIFO 算法有 Belady 現象
- LRU 算法沒有 Belady 現象
LRU,FIFO 和 Clock 的比較
- LRU 算法和 FIFO 本質上都是先進先出的思路
- LRU 依據頁面的最近訪問時間排序
- LRU 需要動態地調整順序
- FIFO 依據頁面進入內存的時間排序
- FIFO 的頁面進入時間是固定不變的
- LRU 可退化成 FIFO
- 如頁面進入內存後沒有被訪問,最近訪問時間與進入內存的時間相同
- 例如:給進程分配3個物理頁面,邏輯頁面的訪問順序爲1,2,3,4,5,6,1,2,3…
- LRU 算法性能較好,但系統開銷較大
- FIFO 算法系統開銷較小,會發生 Belady 現象
- Clock 算法是它們的折中
- 頁面訪問時,不動態調整頁面在鏈表中的順序,僅做標記
- 缺頁時,再把它移動到鏈表末尾
- 對於未被訪問的頁面,Clock 和 LRU 算法的表現一樣好
- 對於被訪問過的頁面,Clock 算法不能記錄準確訪問順序,而 LRU 算法可以
全局頁面置換算法
- 背景:局部置換算法沒有考慮進程訪存差異
- 思路:全局置換算法爲進程分配可變數目的物理頁面
- 全局置換算法要解決的問題
- 進程在不同階段的內存需求是變化的
- 分配給進程的內存也需要在不同階段有所變化
- 全局置換算法需要確定分配給進程的物理頁面數
CPU 利用率和併發進程數的關係
- CPU 利用率與併發進程數存在相互促進和制約的關係
- 進程數少時,提高併發進程數,可提高 CPU 利用率
- 併發進程導致內存訪問增加
- 併發進程的內存訪問會降低了訪存的局部性特徵
- 局部性特徵的下降會導致缺頁率上升和 CPU 利用率下降
工作集
- 一個進程當前正在使用的邏輯頁面集合,可表示爲二元函數 W(t,△)
- t 是當前的執行時刻
- △ 稱爲工作集窗口 ( working-set window ),即一個定長的頁面訪問時間窗口
- W(t,△) 是指在當前時刻 t 前的 △ 時間窗口中的所有訪問頁面所組成的集合
- |W(t,△)| 指工作集的大小,即頁面數目
- 工作集的變化
- 進程開始執行後,隨着訪問新頁面逐步建立較穩定的工作集
- 當內存訪問的局部性區域的位置大致穩定時,工作集大小也大致穩定
- 局部性區域的位置改變時,工作集快速擴張和收縮過渡到下一個穩定值
常駐集
- 在當前時刻,進程實際駐留在內存當中的頁面集合
- 工作集和常駐集的關係
- 工作集是進程在運行過程中固有的性質
- 常駐集取決於系統分配給進程的物理頁面數目和頁面置換算法
- 缺頁率和常駐集的關係
- 常駐集 ⊇ 工作集時,缺頁較少
- 工作集發生劇烈變動(過渡)時,缺頁較多
- 進程常駐集大小達到一定數目後,缺頁率也不會明顯下降
- 工作集和常駐集的關係
工作集置換算法
- 思路:換出不在工作集中的頁面
- 窗口大小 τ
- 當前時刻前 τ 個內存訪問的頁引用是工作集,τ 被稱爲窗口大小
- 實現方法
- 訪存鏈表:維護窗口內的訪存頁面鏈表
- 訪存時,換出不在工作集的頁面;更新訪存鏈表
- 缺頁時,換入頁面;更新訪存鏈表
缺頁率( page fault rate )
缺頁次數 / 內存訪問次數 或 缺頁平均時間間隔的倒數
- 影響缺頁率的因素
- 頁面置換算法
- 分配給進程的物理頁面數目
- 頁面大小
- 程序的編寫方法
缺頁率置換算法( PFF,Page-Fault-Frequency )
- 原理
- 通過調節常駐集大小,使每個進程的缺頁率保持在一個合理的範圍內
- 若進程缺頁率過高,則增加常駐集以分配更多的物理頁面
- 若進程缺頁率過低,則減少常駐集以減少它的物理頁面
- 通過調節常駐集大小,使每個進程的缺頁率保持在一個合理的範圍內
- 實現
- 訪存時,設置引用位標誌
- 缺頁時,計算從上次缺頁時間 tlast 到現在 tcurrent 的時間間隔
- 如果 tcurrent - tlast > T,則置換所有在 [ tlast , tcurrent ] 時間內沒有被引用的頁
- 如果 tcurrent - tlast <= T,則增加缺失頁到常駐集中
抖動問題
- 抖動
- 進程物理頁面太少,不能包含工作集
- 造成大量缺頁,頻繁置換
- 進程運行速度變慢
- 產生抖動的原因
- 隨着駐留內存的進程數目增加,分配給每個進程的物理頁面數不斷減少,缺頁率不斷上升。
- 操作系統需在併發水平和缺頁率之間達到一個平衡
- 選擇一個適當的進程數目和進程需要的物理頁面數
負載控制
- 通過調節併發進程數 ( MPL ) 來進行系統負載控制
- ∑WSi = 內存大小
- 平均缺頁間隔時間 ( MTBF ) = 缺頁異常處理時間( PFST )