這是一本強調從實踐中學理念的計算機體系結構的教材。作者結合自身從事國產龍芯高性能通用處理器研制的實踐,以準確精練、生動活潑的語言,將計算機體系結構的知識深入淺出地傳授給讀者。
全書共13章,第1~4章從計算機體系結構的研究內容和發展趨勢、二進制和邏輯電路、指令系統結構等方面介紹計算機體系結構的基礎內容。第5~7章從靜態流水線、動態流水線、多發射數據通路等方面介紹指令流水線結構。第8~11章從轉移預測、功能部件、高速緩存、存儲管理等方面介紹處理器的模塊級結構。第12章介紹多處理器結構。第13章主要介紹作者在龍芯處理器設計過程中的經驗教訓。
本書適合作為高等學校計算機專業的高年級本科生、研究生的教材,也可以作為相關工程技術人員的學習參考書。
2002年初,我剛開始龍芯處理器的研制沒多久,中科院計算技術研究所負責研究生教育的徐志偉老師就找我說有沒有可能在計算技術研究所開設一門計算機系統結構方面的“大課程”。他進一步解釋說,在國外很好的學校經常有這樣的課程,讓學生每天都忙得“死去活來”,熬夜到凌晨兩三點才能完成作業,但從中還“真正能學到東西”。我便欣然應允。
我從2002年秋季開始給計算技術研究所博士生開設“處理器設計”課程,講課后才知道給學生上課比做研究難。一方面是因為授課比做研究在內容上要求更加全面系統,尤其是講體系結構課程,除了體系結構本身外,還需要對操作系統、編譯器原理、晶體管原理和基本工藝流程等相關領域的知識融會貫通;另一方面做研究時很多內容只要宏觀了解就可以了,但授課就必須對其搞清楚,不清楚就不敢講或者講起來不生動。例如,在龍芯處理器設計時我安排了專門的人負責浮點模塊,因為自己對于IEEE的浮點數據格式標準只是大致了解,但要給學生講自己就得搞清楚;又如,在講TLB時,就得搞清楚操作系統的存儲管理,否則越講學生就越糊涂。基于上述原因,這門課程幾乎花掉了我前3年的所有業余時間,每一講都至少需要花一周的時間做準備,而且每一年都要對講義做大幅度調整,成為一個沉重的負擔。經過3年的積累,課程的章節框架才基本定型。
在此基礎上,2005年開始在中國科學院研究生院同時針對碩士和博士講授“高性能計算機系統結構”課程。碩士和博士課程的主要區別在于作業和考試內容不同。由于要針對碩士講授,因此在基礎性方面又做了補充和加強,并根據授課的實際需要每年再對各章的內容進行了調整和完善。到2008年,準備根據講課的內容出版一部教材,因此對2008年的講授進行了錄音整理。為了增加教材的可讀性和趣味性,在整理教材時保持了第一人稱的形式,同時盡量做到句子及內容的簡潔和嚴謹。
本教材具有如下幾個特點。
一是基礎性,在快速變化的體系結構學科中總結出其中不變的原理性東西。計算機體系結構發展得很快,不斷有新的內容出現,但幾十年來積淀下來的東西并不多。關鍵是要發現快速變化中不變的原理性的東西,如果掌握了這些原理,就能以不變應萬變。因此,在教材編寫時“不趕時髦”且“不跟風”,把計算機體系結構在幾十年的發展過程中形成的里程碑的工作講透,重點介紹具體結構背后的原理和思路。
二是系統性,做到對體系結構、基礎軟件、電路和器件的融會貫通。根據我自己從事處理器設計的經驗,一個體系結構的設計者就像一個帶兵打仗的將領,結構設計就是“排兵布陣”。更重要的是要“上知天文,下知地理”。所謂“上知天文”,指的是在結構設計過程中要充分地了解與處理器聯系緊密的操作系統、編譯器以及應用程序的原理和行為;所謂“下知地理”,指的是在做結構設計時要充分考慮到所設計的模塊和功能部件的電路和版圖結構。要做到一以貫之。例如在打字時,要很清楚地知道從按鍵盤到屏幕上出現一個字的過程中應用程序、操作系統、硬件、芯片、晶體管等的完整的交互行為。
三是實踐性,做“在硅上工作(work on silicon)”的設計。在龍芯處理器的研發中深刻感覺到,計算機體系結構是實踐性很強的學科。因此,在本教材的內容中充分結合了龍芯處理器研發過程中獲得的體驗,強調要做work on silicon的設計,而不要停留在work on paper的設計上。本教材的最后一章“實踐是最好的課堂”,通過龍芯研制過程中發生的10個故事來進一步強調學習計算機體系結構設計實踐的重要性。此外,在教材的習題部分安排了不少需要學生動手實踐的內容。這些習題是對內容的延伸,需要學生在領會教材內容的精神之后進行發揮。
由于體系結構這門學科發展迅速,涉及面廣,因此本教材中難免有不當和疏漏之處,敬請批評指正。同時我也意識到,以活潑生動的形式編寫教材是一種大膽的嘗試,需要面臨很多挑戰。因此,非常歡迎使用本教材的教師和學生對本教材提出寶貴意見。
胡偉武2017年暑期前言計算機體系結構(第2版)
第5章靜態流水線前4章分別介紹了計算機系統結構的基本概念、二進制和邏輯電路以及指令系統結構。有了這些基礎,這一章以一個簡單的CPU為例介紹CPU的流水線設計,后面2章再介紹比較復雜的流水線和多發射結構。
我們從MIPS指令集揀選部分代表性的指令作為簡單CPU需要實現的指令集,其中指令及其編碼列舉在表5.1中,指令的具體含義及指令集的其他定義請參看本書的第4章。
表5.1簡單CPU指令和指令編碼t第5章靜態流水線計算機體系結構(第2版)5.1數據通路設計基于指令系統的定義,先設計這個簡單CPU的數據通路,其主要模塊包括一個指令存儲器、一個數據存儲器、一個通用寄存器堆、一個指令寄存器(IR)和一個程序計數器(PC),如圖5.1所示。
圖5.1主要數據通路CPU工作時,首先用PC作為地址去指令存儲器中取指令。PC的值是怎么來的呢?有兩種情況,第一種是執行完一條指令順序執行時,下一條指令的PC(Next PC,NPC)的值是PC+4,因為指令占4個字節;第二種是執行轉移指令時NPC值是延遲槽PC+offset。因為延遲槽指令總是需要執行的,所以當前指令是跳轉的轉移指令時并不能立即修改PC為跳轉目標,只能是延遲槽指令在CPU里時才能修改。這樣,生成NPC的部分有一個2選1邏輯根據轉移指令跳轉是否成功來選擇offset值和4,選擇之后再由一個加法器跟PC的值相加,并送到PC中。然后,根據這個PC的值到指令存儲器取指,指令取出來以后放到指令寄存器IR中。IR中的指令包含操作碼(op)和功能碼(func),目標寄存器號(rd),兩個源寄存器號(rs、rt),還有立即數/偏移量(imm),其中立即數/偏移量有16位,與rd和func域有部分重疊。
通用寄存器堆、運算部件和存儲器的通路由IR中的域統一控制。通用寄存器的內部電路結構如圖5.2所示,其讀地址RA1通過控制一個32選1邏輯從32組寄存器中選出一組將其值輸出至RD1,同樣的RA2控制另一個32選1邏輯從32組寄存器中選出另一組將其值輸出至RD2;當發生寫操作時,寫地址WA1通過譯碼器得到各組的選擇信號再與上全局寫使能WE1形成每一組寄存器的寫使能,用來控制將寫入數據WD1寫入到相應的寄存器組中。IR的rs域連接到通用寄存器堆的讀端口1的地址輸入,從中選出一個將其值送到ALU的其中一端;IR的rt域連接到通用寄存器堆的讀端口2的地址輸入,從中也選出一個值來,并和符號擴展后的立即數/偏移量2選1后送到ALU的另外一端。這是因為ADDIU、LW和SW指令不用寄存器讀出的值作為第二個源操作數進行運算,而是用指令中的立即數/偏移量進行運算。轉移指令也用到立即數/偏移量,但僅在計算NPC時使用,這里我們使用獨立的加法器進行NPC的計算。ALU完成計算操作之后要把算術運算或邏輯運算的結果寫回到通用寄存器堆里去,具體寫回到哪個寄存器由指令中的rd或rt域來控制,目標連接到通用寄存器堆的寫端口1的地址輸入,進而選中一個寄存器并打開其寫使能。對于LW指令來說,其目標寄存器號來自于指令的rt域而非其他指令的rd域,所以需要通過一個2選1邏輯選擇出目標寄存器號。訪存指令LW和SW把ALU的運算結果作為訪存地址。LW從數據存儲器中把值取出,然后寫回到目標寄存器去,所以寫入通用寄存器堆的數據也需要通過一個2選1邏輯從ALU運算結果和數據存儲器讀出結果之間選擇。SW將寄存器堆中讀出的值寫入到數據存儲器中。
圖5.2寄存器堆電路結構上述描述實現了這個CPU中的主要數據通路,并涵蓋了指令系統中定義的所有指令,但沒有描述這個通路的控制邏輯部分。下面我們一步一步地往里加東西。
5.2控制邏輯設計實現了CPU的數據通路之后,下面先添加CPU的控制邏輯?刂七壿嫺鶕噶畹囊罂刂茢祿跀祿分辛鲃。
從上述數據通路可以看出,為了讓數據根據指令的要求在數據通路中正確地流動,需要對以下通路進行控制: 計算PC的加法器是否需要看轉移跳轉情況決定是加4還是加offset(C1);是選擇寄存器的值還是選擇立即數作為ALU的第二個源操作數(C2);ALU做什么運算(ALUOp);運算結果是把ALU的運算結果寫回,還是把從數據存儲器讀出來的結果寫回(C3);目的寄存器號是來自指令的rd域還是rt域(C4);什么情況下使能通用寄存器堆的寫使能(C5),因為有一些指令是不寫寄存器的,例如SW指令和轉移指令;什么情況下使能數據存儲的寫使能(C6)。
根據指令的功能和數據通路的情況,表5.2給出了CPU中控制邏輯的真值表,其中X表示是0或1無所謂。
……