Getting Physical With Memory
嘗試理解復雜的系統時,你經常能通過去掉抽象層而直接看底層中學到很多東西。本著這種情況,我們從最簡單最基本的層面看內存和I/O端口:處理器和總線間的接口。這些細節構成了更高層的概念,如Core i7對線程同步的需求。當然,作為一名程序員,我會忽略掉只有電子工程的人才會關心的東西(電路結構)。再看一下我們的朋友Core2:
一顆Core2有775根管腳,其中有一半只供電,不用于數據傳輸。一旦你將這些管腳按功能分好組,處理器的物理接口看起來驚人的簡單。上圖顯示了與內存或I/O操作有關的關鍵管腳:地址線、數據管腳和請求管腳。這些操作是作為前端總線(FSB)事務的一部分存在的。前端總線事務分為5個階段:仲裁、請求、解碼、回應和數據??v觀各階段,FSB的各組件發揮著不同的作用,又稱為代理。通常代理就是全部處理器加上北橋芯片。
這里我們只關注請求階段,該階段的請求代理(通常是處理器)會輸出2個包。下面是第1個包里最重要的一些位,它們通過地址和請求管腳輸出:
地址線輸出事務的起始物理內存地址。這個地址需要33位,但它占據的卻是3-35位(而不是0-32位),0-2位都是0。于是我們得到了一個36位的地址,按8字節對齊,可以尋址64GB的物理內存。這就是Pentium PRo的場景。請求管腳指定了事務被初始化成什么類型。對于I/O請求,地址線指定了一個I/O端口,而不是內存地址。在輸出完第一個包后,相同的管腳會在接下來的總線周期內傳輸第2個包:
特征信號(attribute signal)很有趣:它們反映了Intel處理器中的5種內存緩存行為。請求代碼將特征信號放到FSB上,這樣其它處理器就知道這個事務會如何影響它們的緩存,以及內存控制器(北橋)該表現成什么樣。處理器主要通過查看內核維護的頁表來決定指定內存區域的類型。
通常來說內核會將所有RAM內存視為寫回(write-back)模式,目的是達到最佳性能。寫回模式下內存訪問的單位是緩存線(cache line),在Core 2上是64字節。程序讀內存中的1個字節,處理器也會將整個緩存線的內容載入到L2和L1緩存中。當程序寫內存時,處理器只修改緩存中對應的緩存線,而不會直接修改主存。隨后在需要將修改后的內容寫回主存時,每個緩存線會被一次寫回。所以大多數請求的長度域都是11,代表64位。下面是讀不在緩存中的數據的一個示例:
Intel機器上一些物理內存區段被映射為設備,像硬盤和網卡。驅動程序就可以直接讀寫內存來與它們的設備通信。內核在頁表中將這些內存區標記為不可緩存。對不可緩存的內存區的訪問會被完全復制到總線上(而不會訪問緩存)。這種場景中我們可以讀寫任意大小的數據(不受緩存線的限制)。參見上面的packet B。
上面討論的基本原理有許多實際影響。例如:
新聞熱點
疑難解答