1. 程式人生 > >《深入理解計算機系統》儲存器層次結構——讀書筆記

《深入理解計算機系統》儲存器層次結構——讀書筆記

一、儲存技術

      1、 基本的儲存技術包括隨機儲存器(RAM)、非易失性儲存器(ROM)和磁碟。RAM分靜態RAM(SRAM)和動態RAM(DRAM)。SRAM快些,也貴些,主要用做CPU晶片上的快取記憶體,也可以用作晶片下的快取記憶體。DRAM慢些,便宜些,主要用作駐村和圖形幀緩衝區。ROM也叫做只讀儲存器,即使在斷電的情況下,也能保持他們的資訊,它們用來儲存韌體。

      2、傳統的DRAM晶片單元被分成d個超單元,每個超單元由w個DRAM單元組成。一個dxW的DRAM總共儲存了dw位資訊。一個16x8的DRAM晶片組織如下圖所示:

                                                                        

      3、電路設計者將DRAM組織成二維陣列而不是線性陣列的一個原因是降低晶片上地址引腳的數量。(因為每個引腳一次只能傳送一位)讀一個DRAM超單元內容的方式如下圖所示:

                                     

     DRAM晶片包裝在儲存器模組中,示例模組用8個64Mbit的8Mx8的DRAM晶片,總共儲存64MB(兆位元組),如下圖所示:

                                               

       4、增強的DRAM:FPM DRAM , EDO DRAM , SDRAM , DDR DRAM , RDRAM , VRAM。

       5、訪問主存,資料流通過匯流排在CPU和DRAM主存之間來來回回。

            movl A, %eax指令會發生如下流程:

    

      movl %eax, A指令會發生如下流程:

        

      6、磁碟儲存(基本都沒看)

         固態硬碟是一種基於快閃記憶體的儲存技術。

二、區域性性

      1、區域性性通常分兩種不同的形式,時間區域性性和空間區域性性。有良好區域性性的程式比區域性性差的程式執行的更快。在一個有良好時間區域性性的程式中,被引用過一次的儲存器位置很可能在不遠的將來被多次引用;具有良好控制元件區域性性的程式中,如果一個儲存器被引用一次,那麼程式可能在不久的將來引用附近的一個儲存器位置。

      2、對程式資料引用的區域性性

            a)一維陣列示例如下:

                         

       對於sum來說,有很好的時間區域性性,因為sum是標量,對於sum來說,沒有空間區域性性;對於變數v,有很好的控制元件區域性性,但是因為每個向量元素只被訪問一次,因此時間區域性性很差。因此,總體來說,sumvec函式有很好的區域性性。

        b)二維陣列示例如下:

         該段程式碼有很好的區域性性:

                            

       該段程式碼區域性性不好:

                             

      3、取指令區域性性

          因為程式指令是存放在儲存器中的,CPU必須取出這些指令,所以我們也能評價一個程式關於取指令的區域性性。例如,上述一維陣列示例中,for迴圈中的指令是按照連續的儲存器順序執行的,因此迴圈有良好的空間區域性性。因為迴圈體會被執行多次,所以也有很好的時間區域性性。

      4、區域性性小結

       一些量化評價一個程式中區域性性的簡單原則:

       重複引用同一個變數從的程式有良好的時間區域性性;

       對於步長為k的引用模式的程式,步長越小,空間區域性性越好。具有步長為1的引用模式的程式有很好的空間區域性性;

       對於取指令來說,迴圈有很好的時間和空間區域性性。迴圈體越小,迴圈迭代次數越多,區域性性越好。

三、儲存器層次結構

       儲存器層次結構的中心思想是,對於每個k,位於k層的更快更小的儲存裝置作為位於k+1層的更大更慢的儲存裝置的快取。資料總是以塊大小作為傳送單元在第k層和k+1層之間來回拷貝的。儲存器層次結構示例如下圖所示:

                                             

       幾個基本術語:快取命中,快取不命中(冷不命中,衝突不命中,容量不命中)

四、快取記憶體儲存器

       1、通用的快取記憶體儲存器結構

(m=t+s+b)

      2、直接對映快取記憶體

          每組只有一行的快取記憶體叫直接對映快取記憶體。快取記憶體確定一個請求是否命中,然後抽取出被請求的字的過程,分為三步:1)組選擇 2)行匹配 3)字抽取

          a)組選擇

                                        

       b)直接對映快取記憶體行匹配

            當且僅當設定了有效位,而且告訴快取行中的標記與w的地址中標記相匹配時,這一行中包含w的一個拷貝。(有效位+標記)

       c)直接對映快取記憶體中的子選擇

            塊偏移位提供了所需要的字的第一個位元組的偏移。

                      

3、綜合示例

     假設我們有一個直接對映快取記憶體,描述如下:(S,E,B,m)=(4,1,2,4),即4個組,每個組1行,每個塊2個位元組,地址是4位。這裡假設每個字都是單位元組,每次都讀1個字。由上得知,

                         

                                 圖 分析過程                                                                                                圖 完整的直接對映快取記憶體的4位地址空間

    示例過程如下:初始時,快取記憶體是空的:

                                                                  

   a)讀地址0的字。因為組0的有效位是0,快取不命中,所以快取記憶體從儲存器取出塊0,,並存儲在組0中。然後快取記憶體返回取出的快取記憶體行的m[0]。

                                                                   

   b)讀地址1的字。快取記憶體命中。

   c)度地址13的字。

                                                                   

   d)讀地址8的字。(組0的行確實有效,但標記不匹配)

                                                                    

    e)讀地址0的字。又發生快取不命中,因為前面引用地址8時,剛好替換了塊8。

                                                                    

   6、直接對映快取記憶體中的衝突不命中

        以下程式碼容易產生抖動問題:

                                                    

        簡單來說,即使程式有良好的空間區域性性,而且我們的快取記憶體中也有足夠的空間來存放x[i]和y[i]的塊,每次引用還是會引起衝突不命中,這是因為這些塊被對映到了同一個快取記憶體組。參考如下表:

                                           

      採用如下方法,可以消除抖動,把x定義為float x[12],在x結尾加了填充,x[i]和y[i]現在就對映到了不同的組:

                                          

    7、組相連快取記憶體:每個組都儲存有多於一個的快取記憶體行。

    8、全相聯快取記憶體:只有一個組,這個組包含所有的快取記憶體行。

    9、有關寫的問題

      a)寫一個已經快取了的字w寫命中,兩種方式:直寫和寫回。

          直寫:立即將w的快取記憶體塊寫回到緊接著的低一層中。

          寫回:儘可能的推遲儲存器更新,只有當替換演算法要驅逐更新過的塊時,才把它寫到緊接著的低一層中。

     b)處理寫不命中情況:寫分配和非寫分配

五、編寫快取記憶體友好的程式碼

    1、儲存器山

         儲存器系統的效能不是一個數字就能描述的。相反,它是一座時間和空間區域性性的山,這座山的上升高度差別可以超過一個數量級。要是程式執行在山峰而不是低谷。

    2、示例:重新排列迴圈以提高空間區域性性

         一對nxn矩陣相乘問題:C=AxB。一下是矩陣乘法的六個版本