1. 程式人生 > >作業系統頁面置換演算法c++

作業系統頁面置換演算法c++

作業系統頁面置換演算法

頁面置換演算法:
功能:選擇被置換的物理頁面
目標:儘可能減少頁面的調入調出次數
把未來不再訪問或者短期內不訪問的頁面調出
頁面鎖定:(以下部分)
描述必須常駐記憶體的邏輯頁面,作業系統的關鍵部分,要求響應速度的程式碼和資料,頁表中的鎖定標誌位

置換演算法的評價:
記錄所有儲存單元的軌跡。模擬置換演算法,缺頁率。

區域性置換演算法:
僅限於當前程序佔用的物理頁面
最優演算法(預測未來,沒法實現):置換未來最長時間不使用的頁面,
特徵:缺頁最少,實際系統無法實現,無法預知在每隔頁面在下次訪問前的等待時間。
作為其他演算法的評價依據。

先進先出(FIFO),最近最久未使用算(過去使用,對未來的預測)法,近來與出去之間是否會被使用
時鐘演算法,最不常使用演算法
選擇在記憶體駐留時間最長的頁面進行置換
實現:維護一個記錄所有位於記憶體中的邏輯頁面連結串列
連結串列元素按駐留記憶體的時間排序,
出現缺頁時,進行鏈首去頁面置換。
特徵:
實現簡單
效能較差,調出的頁面可能是經常訪問的
程序分配物理與頁面數增加時,缺頁並不一定減少(Belady現象)
很少單獨使用

最近最久未使用演算法(LRU):統計使用時間 ——–表面優秀演算法,開銷比較大
實現:缺頁時,記錄記憶體中每個邏輯頁面的使用時間,選擇最長時間未使用的頁面進行置換。
實現演算法:
1.連結串列維護,鏈首剛剛使用的頁面,鏈尾最久未使用的頁面
2.棧維護
以下對LRU的改進:

時鐘頁面置換演算法(CLOCK):
1.對頁面的訪問情況大致訪問。
1.資料結構:在頁表中增加訪問位,描述在過去的一段時間內訪問的情況
各個頁面組織成環形連結串列
指標指向最先調入的頁面
特徵在LRU和FIFO折中。
頁面裝入記憶體時,訪問位(存在頁表項,被CPU調整)初始化為0
訪問頁面時,訪問位位置1
缺頁時,從指標當前位置順序查詢環形連結串列,訪問位為0,則置換頁面

改進的時鐘演算法:
增加修改位

最不常使用演算法:(LFU):統計使用次數
思路:缺頁時,置換訪問次數最少的頁面
實現:每個頁面增加一個訪問計數
沒有考慮程式執行的階段問題。

Belady現象:
隨著分配的物理頁面數 的增加,缺頁的次數反而升高
原因:FIFO演算法的置換特徵與程序訪問記憶體的動態特徵矛盾
被它置換出去的頁面並不一定是程序近期不會訪問的

全域性頁面置換演算法:給程序分配可變的物理頁面
置換頁面的選擇範圍是可能換出的頁面
工作集置換演算法:
程序當前正在使用的邏輯頁面集合:W(t,s)t為時間視窗的大小
常駐集:在一段時間內記憶體中的頁, 和工作集是交集,理想情況下工作集等價於常駐集,實際情況訪問的頁不再常駐集(記憶體中)。
思路:換出不再工作集的頁面 (並不一定在缺頁的時候),開銷很大

缺頁率演算法(PFF):
缺頁次數/記憶體訪問次數 或 缺頁的平均時間間隔的倒數(常使用)
影響缺頁率的因素:
頁面置換演算法、分配給程序的物理頁面數目、頁面的大小、程式的編寫方法
通過調整常駐集的大小,使得每個程序的缺頁率保持在一定範圍內
1. 如果缺頁率過高,則增加常駐集分配更多的頁面
2. 如果缺頁率過低,則減少常駐集分配更多的頁面
做法:
訪存設定引用位標誌

抖動和負載控制:
程序物理頁面太少,不能包含工作集
造成大量的缺頁,頻繁置換
程序執行速度變化

作業系統需要在併發和缺頁率之間達到一個平衡

簡單的c++實現缺頁率演算法

缺頁率置換

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<stdlib.h>
#include<string.h>
#include<set>
#include<vector>
using namespace std;

#define  MEM_SIZE 10
//此處記憶體動態分配邏輯物理頁面的大小
int main()
{
    int n=-1;
    int t=4;
    cout<<"-------------缺頁率------------"<<endl;
    cout<<"請輸入程式需要的頁號:"<<endl;

    //cout<<">>:輸入0 選擇缺頁率模式";
    vector<int>mem;

    bool find=false;
    int t1=0;
    int t2=-1;
    set<int>myset;
    while(cin>>n)
    {
           cout<<n<<endl;
           myset.insert(n);
           t2++;
           find=false;
           for( vector<int>::iterator i=mem.begin();i!=mem.end();i++)
           {
                  if(n==*i)
                  {

                     cout<<"記憶體中存在:"<<n<<endl;
                     find =true;            
                   }  
           }

           if (find) continue;

            int aa[MEM_SIZE];
            for(int i=0;i<MEM_SIZE;i++) aa[i]=-1;
            int r=0;
           if((t2-t1)>t)
           {
                        t1=t2;
                        for(set<int>::iterator it=myset.begin();it!=myset.end();it++)
                        {

                              aa[r]=*it;
                              r++;
                              if(r>=MEM_SIZE) r=0;

                        }    
                   myset.clear();    
                   int rr=-1;
                   for( vector<int>::iterator i=mem.begin();i!=mem.end();i++)
                   {     bool findmem=false;
                        rr++;
                         for(int j=0;j<MEM_SIZE;j++)
                         {
                              if(*i==aa[j])
                              {
                               findmem=true;
                               break;                                                
                              }

                         }
                         if(!findmem) mem.erase(i);

                   }                          
                   for(int i=0;i<MEM_SIZE;i++)
                   {
                    if(mem[i]==-1)
                     {
                       mem[i]=n;      
                     }    
                   }                                                                
            }

    }
    return 0;   
}