'編程基礎:Java內存模型難理解,看看計算機內存結構就明白了'

電腦 Java 中央處理器 技術 道以致遠 2019-07-20
"
"
編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

深挖底層

前面層級發文說過計算機內存體系的相關概念,本文繼續詳細說一下有關計算機內部存儲體系的組織結構和每一個的相關細節。

我們都瞭解了,計算機的內部存儲有暫時寄存型的,比如集成在CPU裡的各類寄存器,還有高速緩存寄存器,它們位於CPU和我們的主內存之間,當然這種高速緩存器還分了一級和二級等,然後就是我們的主內存存儲器以及次級內存存儲,到外部的硬盤和磁帶之類的永久性存儲設備。

無疑這其中跟我們編程關係最密切的就是高速緩存和主內存,所以我們在詳細說一下它們具體的細節內容。

CPU的各類寄存器就不說了,因為它們集成在CPU單元裡,所以容量有限,特點是能夠支持CPU運算,速度極快,但是好東西都貴,所以不可能把它們的容量搞的很大。如此為了進一步發揮CPU的性能效率,只能在寄存器和主內存之間在添加一類緩衝容器,這就是高速緩衝存儲器。

高速緩衝存儲器是一種特殊的高速存儲器,它用來加速主內存內容與高速的CPU同步的。它比主存或磁盤內存更貴,但比CPU寄存器便宜。是一種非常快的內存類型,它充當RAM和CPU之間的緩衝區。

它可以用來保存CPU頻繁請求的數據和指令,以便在需要時立即提供給CPU,而不用去訪問RAM。

"
編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

深挖底層

前面層級發文說過計算機內存體系的相關概念,本文繼續詳細說一下有關計算機內部存儲體系的組織結構和每一個的相關細節。

我們都瞭解了,計算機的內部存儲有暫時寄存型的,比如集成在CPU裡的各類寄存器,還有高速緩存寄存器,它們位於CPU和我們的主內存之間,當然這種高速緩存器還分了一級和二級等,然後就是我們的主內存存儲器以及次級內存存儲,到外部的硬盤和磁帶之類的永久性存儲設備。

無疑這其中跟我們編程關係最密切的就是高速緩存和主內存,所以我們在詳細說一下它們具體的細節內容。

CPU的各類寄存器就不說了,因為它們集成在CPU單元裡,所以容量有限,特點是能夠支持CPU運算,速度極快,但是好東西都貴,所以不可能把它們的容量搞的很大。如此為了進一步發揮CPU的性能效率,只能在寄存器和主內存之間在添加一類緩衝容器,這就是高速緩衝存儲器。

高速緩衝存儲器是一種特殊的高速存儲器,它用來加速主內存內容與高速的CPU同步的。它比主存或磁盤內存更貴,但比CPU寄存器便宜。是一種非常快的內存類型,它充當RAM和CPU之間的緩衝區。

它可以用來保存CPU頻繁請求的數據和指令,以便在需要時立即提供給CPU,而不用去訪問RAM。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

這種高速緩存內存用於減少從主內存訪問數據的平均時間。緩存是一種更小、更快的內存,它存儲來自經常使用的主內存位置的數據副本。CPU中有多種不同的獨立緩存,用於存儲指令和數據。

計算機內補存儲層級

  • L1(各類寄存器):它是一種存儲和接受數據的內存類型,數據立即存儲在CPU中。最常用的寄存器有累加器、程序計數器、地址寄存器等。
  • L2(高速緩存存儲器):它是速度最快的內存,具有更快的訪問時間,數據被臨時存儲以便更快地訪問。
  • L3(主內存存儲器):計算機當前工作的內存很小,一旦斷電,數據就不再留在內存中
  • L4(次級存儲器):它是外部存儲器,它不像主存儲器那樣快,但是數據永久地留在這個存儲器中。

高速緩存的性能測量方面

當處理器需要對主內存中的某個位置進行讀取或寫入時,它首先檢查緩存中的對應條目。如果處理器發現內存位置在緩存中,也就是命中緩存,因此會直接從緩存中讀取數據。

如果處理器沒有在緩存中找到內存位置,就會發生緩存丟失。對於緩存丟失,緩存分配一個新條目並從主內存中複製數據,然後從緩存的內容中完成請求。高速緩存的性能通常是通過一個稱為命中率的量來度量的。

我們可以使用更大的緩存塊、更高的關聯性、更高的命中率、減少脫靶率,更小的錯過懲罰以及更短的命中緩存的時間來提高緩存性能。

"
編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

深挖底層

前面層級發文說過計算機內存體系的相關概念,本文繼續詳細說一下有關計算機內部存儲體系的組織結構和每一個的相關細節。

我們都瞭解了,計算機的內部存儲有暫時寄存型的,比如集成在CPU裡的各類寄存器,還有高速緩存寄存器,它們位於CPU和我們的主內存之間,當然這種高速緩存器還分了一級和二級等,然後就是我們的主內存存儲器以及次級內存存儲,到外部的硬盤和磁帶之類的永久性存儲設備。

無疑這其中跟我們編程關係最密切的就是高速緩存和主內存,所以我們在詳細說一下它們具體的細節內容。

CPU的各類寄存器就不說了,因為它們集成在CPU單元裡,所以容量有限,特點是能夠支持CPU運算,速度極快,但是好東西都貴,所以不可能把它們的容量搞的很大。如此為了進一步發揮CPU的性能效率,只能在寄存器和主內存之間在添加一類緩衝容器,這就是高速緩衝存儲器。

高速緩衝存儲器是一種特殊的高速存儲器,它用來加速主內存內容與高速的CPU同步的。它比主存或磁盤內存更貴,但比CPU寄存器便宜。是一種非常快的內存類型,它充當RAM和CPU之間的緩衝區。

它可以用來保存CPU頻繁請求的數據和指令,以便在需要時立即提供給CPU,而不用去訪問RAM。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

這種高速緩存內存用於減少從主內存訪問數據的平均時間。緩存是一種更小、更快的內存,它存儲來自經常使用的主內存位置的數據副本。CPU中有多種不同的獨立緩存,用於存儲指令和數據。

計算機內補存儲層級

  • L1(各類寄存器):它是一種存儲和接受數據的內存類型,數據立即存儲在CPU中。最常用的寄存器有累加器、程序計數器、地址寄存器等。
  • L2(高速緩存存儲器):它是速度最快的內存,具有更快的訪問時間,數據被臨時存儲以便更快地訪問。
  • L3(主內存存儲器):計算機當前工作的內存很小,一旦斷電,數據就不再留在內存中
  • L4(次級存儲器):它是外部存儲器,它不像主存儲器那樣快,但是數據永久地留在這個存儲器中。

高速緩存的性能測量方面

當處理器需要對主內存中的某個位置進行讀取或寫入時,它首先檢查緩存中的對應條目。如果處理器發現內存位置在緩存中,也就是命中緩存,因此會直接從緩存中讀取數據。

如果處理器沒有在緩存中找到內存位置,就會發生緩存丟失。對於緩存丟失,緩存分配一個新條目並從主內存中複製數據,然後從緩存的內容中完成請求。高速緩存的性能通常是通過一個稱為命中率的量來度量的。

我們可以使用更大的緩存塊、更高的關聯性、更高的命中率、減少脫靶率,更小的錯過懲罰以及更短的命中緩存的時間來提高緩存性能。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

緩存映射

由於越靠近CPU的緩存性能越好,但是空間也越小,如果想將外層更多的數據裝入到內層緩存,就需要採用映射機制了。目前對於高速緩存與主內存之間的映射機制主要有三種分別是:

直接映射關聯映射集合關聯映射

直接映射技術最簡單,就是直接將主內存每個塊映射到一個可能的高速緩存行上。 或在直接映射中,將每個內存塊分配給緩存中的特定行。如果在需要加載新塊時,如果該行被先前的內存佔用了,則先前的塊會被丟棄。

其地址空間分為索引字段和標記字段兩部分。緩存用來存儲其標記字段,而其餘存儲在主內存中。

直接映射的性能與命中率成正比。可用如下公式表示:

 i = j mod m

這裡,i 是緩存行數, j 是主內存塊數,m 是緩存中的行數

對於高速緩存訪問,可以將每個主內存地址看作由三個字段組成。最不重要的w位標識主內存塊中唯一的字或字節。在大多數現代計算機中,地址都是字節級的。其餘的s位指定主存的2的s次方塊之一。緩存邏輯將這些s位解釋為s-r位(最重要的部分)的標記和r位的行字段。後一個字段標識緩存的m=2的r次方行之一。

關聯映射

在這種類型的映射中,關聯內存用於存儲內容並同時處理內存單詞。任何塊都可以進入緩存的任何行。這意味著字 id位用於標識塊中需要的字,但是標記成為所有剩餘的位。

這允許在高速緩存內存中的任何位置放置任何字。它被認為是最快和最靈活的映射形式。

集合關聯映射

集合關聯映射是一種增強的直接映射形式,消除了直接映射的缺點。

集合關聯解決了直接映射方法中可能出現的抖動問題。

不是隻有一行數據塊可以映射到緩存中,我們將把幾行放在一起創建一個set集合。然後,主內存中的塊可以映射到指定集合的任何行裡。

集合關聯映射允許緩存中出現的每個單詞在主內存中可以有兩個或多個單詞,用於相同的索引地址。

集合關聯緩存映射結合了最佳的直接映射和關聯緩存映射技術。

在這情況下,由輸個集合構成的緩存,每個都是有一定數量的行構成。

m = v * k
i= j mod v

這裡,i 是緩存集合數,j 是主內存塊數,v 是集合數,m 是緩存集中的行數 ,k 是每個集合中的行數。

"
編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

深挖底層

前面層級發文說過計算機內存體系的相關概念,本文繼續詳細說一下有關計算機內部存儲體系的組織結構和每一個的相關細節。

我們都瞭解了,計算機的內部存儲有暫時寄存型的,比如集成在CPU裡的各類寄存器,還有高速緩存寄存器,它們位於CPU和我們的主內存之間,當然這種高速緩存器還分了一級和二級等,然後就是我們的主內存存儲器以及次級內存存儲,到外部的硬盤和磁帶之類的永久性存儲設備。

無疑這其中跟我們編程關係最密切的就是高速緩存和主內存,所以我們在詳細說一下它們具體的細節內容。

CPU的各類寄存器就不說了,因為它們集成在CPU單元裡,所以容量有限,特點是能夠支持CPU運算,速度極快,但是好東西都貴,所以不可能把它們的容量搞的很大。如此為了進一步發揮CPU的性能效率,只能在寄存器和主內存之間在添加一類緩衝容器,這就是高速緩衝存儲器。

高速緩衝存儲器是一種特殊的高速存儲器,它用來加速主內存內容與高速的CPU同步的。它比主存或磁盤內存更貴,但比CPU寄存器便宜。是一種非常快的內存類型,它充當RAM和CPU之間的緩衝區。

它可以用來保存CPU頻繁請求的數據和指令,以便在需要時立即提供給CPU,而不用去訪問RAM。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

這種高速緩存內存用於減少從主內存訪問數據的平均時間。緩存是一種更小、更快的內存,它存儲來自經常使用的主內存位置的數據副本。CPU中有多種不同的獨立緩存,用於存儲指令和數據。

計算機內補存儲層級

  • L1(各類寄存器):它是一種存儲和接受數據的內存類型,數據立即存儲在CPU中。最常用的寄存器有累加器、程序計數器、地址寄存器等。
  • L2(高速緩存存儲器):它是速度最快的內存,具有更快的訪問時間,數據被臨時存儲以便更快地訪問。
  • L3(主內存存儲器):計算機當前工作的內存很小,一旦斷電,數據就不再留在內存中
  • L4(次級存儲器):它是外部存儲器,它不像主存儲器那樣快,但是數據永久地留在這個存儲器中。

高速緩存的性能測量方面

當處理器需要對主內存中的某個位置進行讀取或寫入時,它首先檢查緩存中的對應條目。如果處理器發現內存位置在緩存中,也就是命中緩存,因此會直接從緩存中讀取數據。

如果處理器沒有在緩存中找到內存位置,就會發生緩存丟失。對於緩存丟失,緩存分配一個新條目並從主內存中複製數據,然後從緩存的內容中完成請求。高速緩存的性能通常是通過一個稱為命中率的量來度量的。

我們可以使用更大的緩存塊、更高的關聯性、更高的命中率、減少脫靶率,更小的錯過懲罰以及更短的命中緩存的時間來提高緩存性能。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

緩存映射

由於越靠近CPU的緩存性能越好,但是空間也越小,如果想將外層更多的數據裝入到內層緩存,就需要採用映射機制了。目前對於高速緩存與主內存之間的映射機制主要有三種分別是:

直接映射關聯映射集合關聯映射

直接映射技術最簡單,就是直接將主內存每個塊映射到一個可能的高速緩存行上。 或在直接映射中,將每個內存塊分配給緩存中的特定行。如果在需要加載新塊時,如果該行被先前的內存佔用了,則先前的塊會被丟棄。

其地址空間分為索引字段和標記字段兩部分。緩存用來存儲其標記字段,而其餘存儲在主內存中。

直接映射的性能與命中率成正比。可用如下公式表示:

 i = j mod m

這裡,i 是緩存行數, j 是主內存塊數,m 是緩存中的行數

對於高速緩存訪問,可以將每個主內存地址看作由三個字段組成。最不重要的w位標識主內存塊中唯一的字或字節。在大多數現代計算機中,地址都是字節級的。其餘的s位指定主存的2的s次方塊之一。緩存邏輯將這些s位解釋為s-r位(最重要的部分)的標記和r位的行字段。後一個字段標識緩存的m=2的r次方行之一。

關聯映射

在這種類型的映射中,關聯內存用於存儲內容並同時處理內存單詞。任何塊都可以進入緩存的任何行。這意味著字 id位用於標識塊中需要的字,但是標記成為所有剩餘的位。

這允許在高速緩存內存中的任何位置放置任何字。它被認為是最快和最靈活的映射形式。

集合關聯映射

集合關聯映射是一種增強的直接映射形式,消除了直接映射的缺點。

集合關聯解決了直接映射方法中可能出現的抖動問題。

不是隻有一行數據塊可以映射到緩存中,我們將把幾行放在一起創建一個set集合。然後,主內存中的塊可以映射到指定集合的任何行裡。

集合關聯映射允許緩存中出現的每個單詞在主內存中可以有兩個或多個單詞,用於相同的索引地址。

集合關聯緩存映射結合了最佳的直接映射和關聯緩存映射技術。

在這情況下,由輸個集合構成的緩存,每個都是有一定數量的行構成。

m = v * k
i= j mod v

這裡,i 是緩存集合數,j 是主內存塊數,v 是集合數,m 是緩存集中的行數 ,k 是每個集合中的行數。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

高速緩存應用

通常,高速緩存內存可以在任何給定的時間內存儲合理數量的主內存塊,但是與主內存中的塊總數相比,這個數量還是很小的。

主內存塊與緩存中內存塊之間的對應關係由映射函數指定。

高速緩存類型:

  • 主高速緩存:主緩存總是位於處理器芯片上。這個緩存很小,它的訪問時間與處理器寄存器的訪問時間相當。
  • 次級高速緩存:次級高速緩存位於主高速緩存和其餘內存之間,它被稱為二級(L2)緩存。通常,二級緩存也駐留在處理器芯片上。

因為高速緩存的大小比主內存小。因此,要檢查主存的哪一部分應該被賦予優先級並加載到高速緩存中,需要根據引用的位置來決定。

引用局域性類型

  • 引用空間局域性:也就是說元素有機會出現在引用點非常接近的地方,下次在查找時更靠近引用點。
  • 引用時間局域性:在這裡最近最少使用算法將被使用,無論何時每當分頁錯誤發生在一個word裡,將不僅在主內存加載word,而且還會加載完整的頁面錯誤。

因為引用空間局域性規則說,如果你引用任何字緊鄰我們寄存器中被引用的字,這就是為什麼我們加載完整頁表,這樣完整塊就會被加載。

"
編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

深挖底層

前面層級發文說過計算機內存體系的相關概念,本文繼續詳細說一下有關計算機內部存儲體系的組織結構和每一個的相關細節。

我們都瞭解了,計算機的內部存儲有暫時寄存型的,比如集成在CPU裡的各類寄存器,還有高速緩存寄存器,它們位於CPU和我們的主內存之間,當然這種高速緩存器還分了一級和二級等,然後就是我們的主內存存儲器以及次級內存存儲,到外部的硬盤和磁帶之類的永久性存儲設備。

無疑這其中跟我們編程關係最密切的就是高速緩存和主內存,所以我們在詳細說一下它們具體的細節內容。

CPU的各類寄存器就不說了,因為它們集成在CPU單元裡,所以容量有限,特點是能夠支持CPU運算,速度極快,但是好東西都貴,所以不可能把它們的容量搞的很大。如此為了進一步發揮CPU的性能效率,只能在寄存器和主內存之間在添加一類緩衝容器,這就是高速緩衝存儲器。

高速緩衝存儲器是一種特殊的高速存儲器,它用來加速主內存內容與高速的CPU同步的。它比主存或磁盤內存更貴,但比CPU寄存器便宜。是一種非常快的內存類型,它充當RAM和CPU之間的緩衝區。

它可以用來保存CPU頻繁請求的數據和指令,以便在需要時立即提供給CPU,而不用去訪問RAM。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

這種高速緩存內存用於減少從主內存訪問數據的平均時間。緩存是一種更小、更快的內存,它存儲來自經常使用的主內存位置的數據副本。CPU中有多種不同的獨立緩存,用於存儲指令和數據。

計算機內補存儲層級

  • L1(各類寄存器):它是一種存儲和接受數據的內存類型,數據立即存儲在CPU中。最常用的寄存器有累加器、程序計數器、地址寄存器等。
  • L2(高速緩存存儲器):它是速度最快的內存,具有更快的訪問時間,數據被臨時存儲以便更快地訪問。
  • L3(主內存存儲器):計算機當前工作的內存很小,一旦斷電,數據就不再留在內存中
  • L4(次級存儲器):它是外部存儲器,它不像主存儲器那樣快,但是數據永久地留在這個存儲器中。

高速緩存的性能測量方面

當處理器需要對主內存中的某個位置進行讀取或寫入時,它首先檢查緩存中的對應條目。如果處理器發現內存位置在緩存中,也就是命中緩存,因此會直接從緩存中讀取數據。

如果處理器沒有在緩存中找到內存位置,就會發生緩存丟失。對於緩存丟失,緩存分配一個新條目並從主內存中複製數據,然後從緩存的內容中完成請求。高速緩存的性能通常是通過一個稱為命中率的量來度量的。

我們可以使用更大的緩存塊、更高的關聯性、更高的命中率、減少脫靶率,更小的錯過懲罰以及更短的命中緩存的時間來提高緩存性能。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

緩存映射

由於越靠近CPU的緩存性能越好,但是空間也越小,如果想將外層更多的數據裝入到內層緩存,就需要採用映射機制了。目前對於高速緩存與主內存之間的映射機制主要有三種分別是:

直接映射關聯映射集合關聯映射

直接映射技術最簡單,就是直接將主內存每個塊映射到一個可能的高速緩存行上。 或在直接映射中,將每個內存塊分配給緩存中的特定行。如果在需要加載新塊時,如果該行被先前的內存佔用了,則先前的塊會被丟棄。

其地址空間分為索引字段和標記字段兩部分。緩存用來存儲其標記字段,而其餘存儲在主內存中。

直接映射的性能與命中率成正比。可用如下公式表示:

 i = j mod m

這裡,i 是緩存行數, j 是主內存塊數,m 是緩存中的行數

對於高速緩存訪問,可以將每個主內存地址看作由三個字段組成。最不重要的w位標識主內存塊中唯一的字或字節。在大多數現代計算機中,地址都是字節級的。其餘的s位指定主存的2的s次方塊之一。緩存邏輯將這些s位解釋為s-r位(最重要的部分)的標記和r位的行字段。後一個字段標識緩存的m=2的r次方行之一。

關聯映射

在這種類型的映射中,關聯內存用於存儲內容並同時處理內存單詞。任何塊都可以進入緩存的任何行。這意味著字 id位用於標識塊中需要的字,但是標記成為所有剩餘的位。

這允許在高速緩存內存中的任何位置放置任何字。它被認為是最快和最靈活的映射形式。

集合關聯映射

集合關聯映射是一種增強的直接映射形式,消除了直接映射的缺點。

集合關聯解決了直接映射方法中可能出現的抖動問題。

不是隻有一行數據塊可以映射到緩存中,我們將把幾行放在一起創建一個set集合。然後,主內存中的塊可以映射到指定集合的任何行裡。

集合關聯映射允許緩存中出現的每個單詞在主內存中可以有兩個或多個單詞,用於相同的索引地址。

集合關聯緩存映射結合了最佳的直接映射和關聯緩存映射技術。

在這情況下,由輸個集合構成的緩存,每個都是有一定數量的行構成。

m = v * k
i= j mod v

這裡,i 是緩存集合數,j 是主內存塊數,v 是集合數,m 是緩存集中的行數 ,k 是每個集合中的行數。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

高速緩存應用

通常,高速緩存內存可以在任何給定的時間內存儲合理數量的主內存塊,但是與主內存中的塊總數相比,這個數量還是很小的。

主內存塊與緩存中內存塊之間的對應關係由映射函數指定。

高速緩存類型:

  • 主高速緩存:主緩存總是位於處理器芯片上。這個緩存很小,它的訪問時間與處理器寄存器的訪問時間相當。
  • 次級高速緩存:次級高速緩存位於主高速緩存和其餘內存之間,它被稱為二級(L2)緩存。通常,二級緩存也駐留在處理器芯片上。

因為高速緩存的大小比主內存小。因此,要檢查主存的哪一部分應該被賦予優先級並加載到高速緩存中,需要根據引用的位置來決定。

引用局域性類型

  • 引用空間局域性:也就是說元素有機會出現在引用點非常接近的地方,下次在查找時更靠近引用點。
  • 引用時間局域性:在這裡最近最少使用算法將被使用,無論何時每當分頁錯誤發生在一個word裡,將不僅在主內存加載word,而且還會加載完整的頁面錯誤。

因為引用空間局域性規則說,如果你引用任何字緊鄰我們寄存器中被引用的字,這就是為什麼我們加載完整頁表,這樣完整塊就會被加載。

編程基礎:Java內存模型難理解,看看計算機內存結構就明白了

內存模型設計之道

概括一下

對於引用局域性我們可以簡單理解成:在時間和空間上都要儘量的將彼此相連的內容儘量放到一起。

空間和時間局部性描述了程序訪問數據(或指令)的兩種不同特性。

如果在時間上被引用的對象在空間上也很接近(如附近的內存地址、磁盤上的鄰近扇區等),則一系列引用具有空間局域性。

如果對同一事物的訪問在時間上聚集在一起,則序列具有時間局域性。

如果一個程序訪問在一個大數組,每個元素讀取一次,然後移動到下一個元素,不重複訪問任何給定的位置,直到它觸及其他位置那麼明確的空間位置而不是時間局部性。

另一方面,如果一個程序在進入另一個隨機子集之前,花費時間反覆訪問數組中位置的隨機子集,那麼它將具有時間局域性,而不是空間局域性。

一個編寫良好的程序將具有的數據結構將一起訪問的東西組合在一起,從而確保空間的局域性。

如果程序很可能在訪問A之後不久訪問B,那麼A和B應該在彼此附近分配。

總結:

這裡所說的這些內部存儲架構以及緩存之間的映射關係,都是我們Java編程中必須要面對的編譯優化和執行優化的理論基礎,理解了這些緩存的差異以及緩存之間如何引用,裝入排出,我們就知道在java性能優化時,編譯器要做的重排,以及對象可見性的規定,其實都是在為統一高速緩存內容和主內存內容的一致性而做的。

"

相關推薦

推薦中...