回覆列表
  • 1 # ZHUA年

    "registers are closer to the ALU than memory"可以認為基本上是對的,這裡先來看看訪問速度的比較:一條彙編指令大概執行過程是(不是絕對的,不同平臺有差異):取指(取指令)、譯碼(把指令轉換成微指令)、取數(讀記憶體裡的運算元)、計算(各種計算的過程,ALU負責)、寫回(將計算結果寫回記憶體),有些平臺裡,前兩步會合併成一步,某些指令也不會有取數或者回寫的過程。再提一下CPU主頻的概念:首先,主頻絕對不等於一秒鐘可以執行的指令個數,每個指令的執行成本是不同的,比如x86平臺裡彙編指令INC就比ADD要快,具體每個指令的時鐘週期可以參考intel的手冊。為什麼要提主頻?因為上面的執行過程中,每個操作都需要佔用一個時鐘週期,對於一個操作記憶體的加法,就需要5個時鐘週期,換句話說,500Mhz主頻的CPU,最多執行100MHz條指令。仔細觀察,上面的步驟裡不包括暫存器操作,對於CPU來說讀/寫暫存器是不需要時間的,或者說如果只是操作暫存器(比如類似mov BX,AX之類的操作),那麼一秒鐘執行的指令個數理論上說就等於主頻,因為暫存器是CPU的一部分。然後暫存器往下就是各級的cache,有L1 cache,L2,甚至有L3的,以及TLB這些(TLB也可以認為是cache),之後就是記憶體,前面說暫存器快,現在說為什麼這些慢:對於各級的cache,訪問速度是不同的,理論上說L1 cache(一級快取)有著跟CPU暫存器相同的速度,但L1 cache有一個問題,當需要同步cache和記憶體之間的內容時,需要鎖住cache的某一塊(術語是cache line),然後再進行cache或者記憶體內容的更新,這段期間這個cache塊是不能被訪問的,所以L1 cache的速度就沒暫存器快,因為它會頻繁的有一段時間不可用。L1 cache下面是L2 cache,甚至L3 cache,這些都有跟L1 cache一樣的問題,要加鎖,同步,並且L2比L1慢,L3比L2慢,這樣速度也就更低了。最後說說記憶體,記憶體的主頻現在主流是1333左右吧?或者1600,單位是MHz,這比CPU的速度要低的多,所以記憶體的速度起點就更低,然後記憶體跟CPU之間通訊也不是想要什麼就要什麼的。記憶體不僅僅要跟CPU通訊,還要透過DMA控制器與其它硬體通訊,CPU要發起一次記憶體請求,先要給一個訊號說“我要訪問資料了,你忙不忙?”如果此時記憶體忙,則通訊需要等待,不忙的時候,通訊才能正常。並且,這個請求訊號的時間代價,就是夠執行幾個彙編指令了,所以,這是記憶體慢的一個原因。另一個原因是:記憶體跟CPU之間通訊的通道也是有限的,就是所謂的“匯流排頻寬”,但,要記住這個頻寬不僅僅是留給記憶體的,還包括視訊記憶體之類的各種通訊都要走這條路,並且由於路是共享的,所以任何請求發起之間都要先搶佔,搶佔頻寬需要時間,頻寬不夠等待的話也需要時間。以上兩條加起來導致了CPU訪問記憶體更慢,比cache還慢。舉個更容易懂的例子:CPU要取暫存器AX的值,只需要一步:把AX給我拿來,AX就拿來了。CPU要取L1 cache的某個值,需要1-3步(或者更多):把某某cache行鎖住,把某個資料拿來,解鎖,如果沒鎖住就慢了。CPU要取L2 cache的某個值,先要到L1 cache裡取,L1說,我沒有,在L2裡,L2開始加鎖,加鎖以後,把L2裡的資料複製到L1,再執行讀L1的過程,上面的3步,再解鎖。CPU取L3 cache的也是一樣,只不過先由L3複製到L2,從L2複製到L1,從L1到CPU。CPU取記憶體則最複雜:通知記憶體控制器佔用匯流排頻寬,通知記憶體加鎖,發起記憶體讀請求,等待迴應,迴應資料儲存到L3(如果沒有就到L2),再從L3/2到L1,再從L1到CPU,之後解除匯流排鎖定。這個連結是個圖,可以看看CPU離主存(main memory)有多遠,這個圖沒畫暫存器,可以理解為:所有的L1 cache下面是暫存器,暫存器下面是CPUFile:Cache,hierarchy-example.svg

  • 中秋節和大豐收的關聯?
  • 為什麼正規場合要穿西服?