2017-08-29 82 views
0
讀取數據

後來試圖在其他一些文件中只讀一次這個變量。所以這個變量是如何從內存中讀取的,它將這個變量放在緩存中,還是從主內存中讀取它。如何CPU從內存?緩存如何發揮<p>我已經寫了一張我在哪裏分配內存變量Bextradata代碼(這是結構的構件也被分配使用malloc)作爲</p> <pre><code>Bextradata = (U8_WMC *) malloc(Size); memset(Bextradata, 0,Size); memcpy(BextraData,pdata + 18,Size); </code></pre> 重要作用

由於提前

+0

取決於您使用的處理器+操作系統平臺。我正在開發我們根本沒有緩存的平臺。 – Vagish

+0

具有按高速緩存線讀取主存儲器的系統(例如,一次32或64字節)。所以,即使你不訪問你的變量,總會有一個機會,它已經被其他代碼讀取了。 –

回答

1

之前,你瞭解CPU的工作,你需要了解一些術語。 CPU由ALU(用於算術和邏輯操作),控制單元和一堆寄存器組成。 CPU中的寄存器數量取決於體系結構並有所不同。存在的寄存器類型是通用寄存器,專用寄存器指令指針和其他一些寄存器。你可以閱讀有關它們。現在,當我們通常說32位處理器或64位處理器時,我們指的是CPU寄存器的大小。

現在讓我們看看下面的代碼:

int a = 10; 
int b = 20; 
a = a + b; 

當加載上面的程序,它的指令存儲在主存儲器。程序中的每條指令都存儲在主存儲器的一個位置。每個位置都有一個特定的大小(再次取決於架構,但我們假設它是一個字節)。每個地點都有一個地址。 RAM中特定位置的地址大小等於指令指針的大小。在64位系統中,指令指針的大小將是64位。這意味着它可以處理高達2^64-1的位置。由於1個位置通常是1個字節,因此理論上64位系統的總RAM可以是16EB。 (對於32位系統,它是2^32-1〜4GB)

現在讓我們看看第一條指令a = 10。這是一個存儲操作。計算機可以執行以下基本操作 - 添加,乘,減,除,存儲,跳轉等。您可以閱讀任何處理器的指令集,以獲取更多信息。指令集又是不同的系統。回頭來看,當程序加載到內存時,指令指針指向第一個地址或基地址。在這種情況下,它是a = 10。該位置的內容被帶到CPU的通用寄存器之一。由此它被送到ALU,ALU明白這是一個存儲操作(cus附加位表示它是存儲操作)。然後,ALU將其存儲到RAM中的一個位置以及緩存中。將其存儲在緩存中的決定取決於編譯器和稱爲硬件預取的概念。當編譯器解析程序時,它會看到經常使用的變量並使它們能夠存儲在緩存中。在這種情況下,我們可以看到變量'a'將被再次使用,以便編譯器向程序添加額外的中間指令,並將其存儲在緩存中。爲什麼?爲了更快的訪問。 (在速度方面始終記住寄存器>高速緩存> RAM>光盤)

第一條指令執行後,指令指針遞增,現在指向第二條指令,即b = 20。同樣的情況發生與此同樣。

第三個是a = a + b。爲此,實際上有四個操作(如果你看看彙編級別),即1)取a,2)取b,3)在a中增加a和b,4)存儲結果。現在由於變量a和b存在於緩存中,它們是從這些位置獲取的。然後添加它們,並將結果存儲回。

我希望你明白它是如何工作的。

另外你需要知道的是,當一個程序加載到主內存中時,它佔據了一定的空間。這個空間被稱爲段。它有一個基地址和一個最終地址。您可以將基地址作爲第一條指令,並將最終地址作爲最後一條指令。如果從您的程序中嘗試解引用指向該段以外的指針,則會出現着名的錯誤 - 分段錯誤。例如:

int *ptr = NULL; 
printf(*ptr); 

這會給我一個分段錯誤,因爲我想提領存儲的地址,其值爲NULL和NULL以來不段,它會給一個賽格故障的指針。

+0

由於變量a和b存在於緩存中,因此它們將從這些位置獲取。然後他們被添加並且結果被存儲回a ::-這是兩個地方更新的結果嗎?我的意思是RAM以及高速緩存 – prashant

+0

它取決於稱爲高速緩存預取的概念。當編譯器編譯代碼時,它會分析特定變量的重現。例如,如果在該指令之後,即a = a + b,你還有一條指令使用了變量a,那麼將它存儲在緩存中也是合乎邏輯的,對吧?編譯器會在編譯過程中通過添加額外的指令來爲你做到這一點。這被稱爲軟件預取。 –

+0

雖然這在概念層面上是正確的,但即使是最簡單的優化編譯器也會意識到代碼與'int a = 30;'相同,並且它不必在任何地方存儲'b'。也許不是'a',這取決於接下來會發生什麼。 –

相關問題