1. 程式人生 > >五級經典流水線執行 時間統計

五級經典流水線執行 時間統計

五級經典流水線執行

時間統計

forwarding策略:

來自EX/MEM 和 MEM/EX 流水線暫存器的ALU結果總是被反饋回ALU的輸入端

也就是,下一條指令,直接可以從上一條指令的EX中獲得資料

但是,forwarding演算法並不是完美的

它需要停頓的資料冒險:

LD/LW 的資料要在MEM結束以後才能將資料傳給下一個指令的ALU(即EX環節)

所以載入指令需要增加一種稱為流水線互鎖 , 以保持正確的執行模式

流水線互鎖檢測冒險 , 並在該冒險被清除之前使流水線停頓

每個時鐘週期只能新增一條指令


關於指令型別:

本實驗提供的指令序列檔案,不包含跳轉指令,只涉及到ALU指令和load/store指令,Trace中會出現的指令型別主要是如下的幾種:

ALU型別:DADD, DSUB, AND, OR, XOR

Load/store型別:LD, SD, LW, SW

模擬器正確性的驗證:

trace4.txt:

DADD R2, R3, R1
DSUB R4,, R2, R1
LW   R7, 0(R1)
DADD R6, R5,, R7
XOR   R5, R6, R4
AND  R3, R5, R2
AND  R3, R5, R2


注意點:

1、只有當LD/LW 的 目的運算元 , 作為下一條指令的元運算元時 , 才會發生停頓!!!!

2、每個始終週期只能執行一條指令

這也是為什麼,最後一條指令要往後再退一格


程式碼:

#include
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    string buffer;
    string str[4];
    string temp = "normal";
    int index = 0;//判斷是否

    int num = 0;

    ifstream in("trace4.txt");
    if (! in.is_open())
    {
        cout << "Error opening file";
        exit (1);
    }

    //初始
    num = 4;

    while (!in.eof() )
    {
        //每執行一條指令至少多一個cycle
        num++;

        //cout << buffer << endl;    getline空格也算一個字元
        getline(in, buffer);/*要用#include*/

        int s = 0, i;
        istringstream stream(buffer);

        stream >> str[0] >> str[1] >> str[2] >> str[3]; //一個字串一個字串地取出

        //去掉逗號
        size_t found;
        for(i=1 ; i<4 ; i++){
            found = str[i].find(',');
            while(found != string::npos){
                str[i] = str[i].erase(found,1);
                found = str[i].find(',');
            }
        }

        //去掉括號,去掉多餘的數字
        if(str[0] == "LD" || str[0] == "LW" || str[0] == "SD" || str[0] == "SW")
            str[2] = str[2].substr(str[2].find("(")+1 ,str[2].find(")")-str[2].find("(")-1);

        //輸出檢驗
        //cout << str[0] << str[1] << str[2] << str[3] << endl;

        //如果是Load的時候,做標記,因為只有在lod的時候會導致 , 整個流水線出現停頓的情況
        if(str[0] == "LD" || str[0] == "LW"){
            temp = str[1];
        }

        else{
            if(temp == "normal")
                continue;
            else{
                //只有當上一個是LD / LW ,且LD / LW 的下一條命令中 , 有上一條命令的目的運算元時
                //會對下一條命令產生影響,否則不會
                if(str[0] == "SD" || str[0] == "SW"){
                    if(str[1] == temp || str[2] == temp )
                        num++;
                        temp = "normal";
                }else{
                    if(str[1] == temp || str[2] == temp || str[3] == temp)
                        num++;
                        temp = "normal";
                }
            }
        }
    }

    cout << "num of cycles =" << num << endl;

    return 0;
}