為什麼需要快取記憶體

2022-09-14 10:54:09 字數 1943 閱讀 8370

title: 為什麼需要快取記憶體

categories:

深入理解計算機系統

我們知道,如果要執行乙個程式,首先得將乙個可執行檔案載入到記憶體當中。那麼問題來了,假如我程式中是要對乙個陣列進行操作,而我陣列的資料又是放在記憶體上的,那麼cpu對每乙個元素進行操作的時候,都要先把資料載入到暫存器上,對暫存器進行操作,然後再儲存到記憶體。而cpu到記憶體的這段時間就好比每次上課的時候回家拿書,我能不能把我需要的書(最近訪問的資料)都先快取到我的小書包裡,每次上課我就從我的小書包裡取出我需要的資料進行操作就ok了。

所以快取記憶體sram介於暫存器與記憶體之間,就是因為處理器發展到現在,速度越來越快,而現代計算頻繁地使用基於sram的快取記憶體,就是為了彌補處理器與記憶體之間的差距,而這種方法行之有效就是因為接下來要講的應用程式的乙個稱為區域性性的基本屬性。

區域性性是什麼呢?

之前在優化程式效能講過,在迴圈裡面盡量用區域性變數累計值,或者是將函式呼叫移出迴圈外,用乙個臨時量代替,原因是訪問乙個區域性變數要比從記憶體中(載入,取值,儲存)或是過程呼叫要快得多(消除了每次迴圈迭代中從記憶體中讀出並將更新值寫回的需要,將每次迭代的記憶體操作從兩次讀和一次寫減少到只需一次讀)。時間區域性性指的就是在這個過程中我反覆要訪問這個變數,那麼這個變數就具有很好的時間區域性性。

空間區域性性指的是訪問乙個變數後,後面要訪問到這個變數附近的資料。

舉個例子,對乙個陣列求和:

int sum = 0;

for(int i = 0; i < n; ++i)

我們可以看到,sum在每次迭代中都要訪問到,有好的時間區域性性。而a[i]是陣列的某乙個元素,訪問一次後,再也不訪問,因此時間區域性性很差,但是之後會訪問到後面的元素,陣列是順序儲存,因此有好的空間區域性性。

那麼快取記憶體到底是怎樣給上述例子提供強有力的支援呢假設記憶體有m=2^m大的位址空間(實際上並不需要是2的冪),位址如下表示:

快取記憶體在中間去s位作組號(s=2s個組),取h位作標記位(h=2h),b位作塊大小(b=2^b)。

這樣做,雖然快取記憶體並沒有記憶體大,但是記憶體的每乙個位址都能快取到sram上,注意,乙個位址對應這個位址上乙個位元組(位元組序列角度),快取記憶體可不會快取你乙個位址上的乙個位元組(太小了,一滴水救火?),如果組好確定,那你後面b=2^b個位址是不是都在我乙個組?那我快取記憶體乙個組直接就存b個位元組大小的塊。打個比方,int a[4]陣列,在記憶體裡連續儲存16個位元組,假如我取b=2,那麼我b=2^4=16個位元組,那麼整個陣列就快取到了快取記憶體中,這個時候我如果訪問a的第乙個元素,如果不在快取中(不命中),那麼我就會從記憶體取對應的16個位元組到快取記憶體中,這個時候結合上面的例子去思考空間區域性性,是不是有種豁然開朗的感覺。

在這裡簡單講一下直接對映快取記憶體和組相聯快取記憶體,直接對映快取記憶體就是乙個組裡面只有一行。相聯快取記憶體呢,乙個組有k行就是k路組相聯快取記憶體。全相聯快取記憶體就是只有乙個組。

那麼現在,cpu要訪問某個資料,對應的要先在快取記憶體裡找有沒有,那麼就根據分析實體地址找到組,行,匹配標記位,看有效位,最後根據塊偏移找到塊中對應資料。

為了使快取記憶體有乙個好的使用效率

如果我們要寫乙個以及快取了的字w,在快取記憶體裡更新了w的副本之後,怎麼更新儲存器層次結構的低一層呢?

有兩種方法:

第一種是直寫,就是立即將w的快取記憶體塊寫回到低一層中。缺點就是每次寫都會引起匯流排流量。

第二種是寫回,就是說我在快取記憶體中更新了副本之後我不馬上寫回到低一層中,如果我還有訪問更新值呢?所以知道我這個w被擠出快取記憶體,我再寫回到低一層。

我們熟悉區域性性之後,就不難理解怎麼樣才能讓程式盡可能執行得快了。

讓最常見得情況執行得快

儘量減少每個迴圈內部得快取不命中數量

後期我會拓展並更新,並相應配圖。

linux DNS快取記憶體

配置名稱伺服器 本機ip 172.25.254.117 1 安裝 bind 軟體包 yum install y bind2 編輯 etc named.conf listen on port 53 開啟埠 allow query 允許訪問 forwarders 如果伺服器沒有這個位址就去訪問250 3...

快取記憶體DNS

dns 客戶端修改dns 服務端yum install bind y firewall cmd permanent add service dns firewall cmd reload setenforce 0 netstat antulpe grep named vim etc named.co...

快取記憶體DNS

yum install bind y systemctl start named 啟動dns服務 此時可能需要在虛擬機器中進行無規律的敲鍵盤,動滑鼠等操作 systemctl enable named firewall cmd add service dns 設定dns可通過火牆 step1 首先配...