快取記憶體和寫緩衝器的記憶體重排序造成的假象(面試)

2021-10-07 19:02:43 字數 1241 閱讀 5920

處理器會將資料寫入寫緩衝器,這個過程是store;從快取記憶體裡讀資料,這個過程是load。寫緩衝器和快取記憶體執行load和store的過程,都是按照處理器指示的順序來的,處理器的重排處理器也是按照程式順序來load和store的。但是有個問題,就是在其他的處理器看到的乙個視覺假象而言,有可能會出現看到的load和store是重排序的,也就是記憶體重排序。

處理器的亂序執行和推測執行,都是指令重排序,這次的是記憶體重排序,因為都是發生在記憶體層面的寫緩衝器和快取記憶體中的。

這個記憶體重排序,有4種可能性:

loadload重排序:乙個處理器先執行乙個l1讀操作,再執行乙個l2讀操作;但是另外乙個處理器看到的是先l2再l1。

storestore重排序:乙個處理器先執行乙個w1寫操作,再執行乙個w2寫操作;但是另外乙個處理器看到的是先w2再w1。

loadstore重排序:乙個處理器先執行乙個l1讀操作,再執行乙個w2寫操作;但是另外乙個處理器看到的是先w2再l1。

storeload重排序:乙個處理器先執行乙個w1寫操作,再執行乙個l2讀操作;但是另外乙個處理器看到的是先l2再w1。

比如說寫緩衝器為了提公升效能,有可能先後到來w1和w2操作了之後,他先執行了w2操作,再執行了w1操作。那這個時候其他處理器看到的可不就是先w2再w1了,這就是storestore重排序。

共享變數:

resource resource = null;

boolean resourceloaded = false;

處理器0:

resource = loadresourefromdisk();

resourceloaded = true;

處理器1:

while(!resourceloaded) catch(exception) {

resource.execute();

類似上面的**,很可能處理器0先寫了resource,再寫了resourceloaded。結果呢,寫緩衝器進行了記憶體重排序,先落地了resourceloaded = true了,此時resource還是null。此時處理器1就會看到resourceloaded = true,就會對resource物件執行execute()方法,此時就會有空指標異常的問題。

類似的情況,快取記憶體和寫緩衝器都可以自己對load和store操作的結果落地到記憶體進行各種不同的重排序,進而造成上述4種記憶體重排序問題的發生。

無法寫入快取記憶體 記憶體與CPU的快取記憶體的關係

我們個人pc都有乙個叫做記憶體的硬體,有4g 8g 16g不等的容量。但我們的cpu執行時執行的指令並不是直接從記憶體中獲取,而是從cpu自身的快取記憶體中獲得指令並執行,指令執行完畢再寫回快取,然後待到特定的時機才把資料在寫回主記憶體。那cpu是如何將比自己容量大的多的記憶體放進自己的快取記憶體中...

LINUX頁快取記憶體和頁回寫

from 頁快取記憶體是linux核心實現的一種主要磁碟快取,它主要用來減少對磁碟的io操作,具體地講,是通過把磁碟中的資料快取到物理記憶體中,把對磁碟的訪問變為對物理記憶體的訪問。為什麼要這麼做呢?一,速度,訪問磁碟的速度要遠低於訪問記憶體的速度 二臨時區域性原理,短時期內集中訪問同一片資料的原理...

16 頁快取記憶體和頁回寫

頁快取記憶體有什麼作用?主要實現linux的磁碟快取,用來減少磁碟的io操作,具體講就是把磁碟中資料快取到物理記憶體,把對磁碟的訪問轉換為對物理記憶體的訪問。磁碟快取記憶體為什麼這麼重要?什麼是臨時區域性原理?在短期內訪問同一片資料區的原理稱為臨時區域性原理 頁快取記憶體有什麼特點?頁快取記憶體的大...