首頁 > 軟體

認識Java底層作業系統與並行基礎

2022-07-29 14:00:03

一、現代計算機硬體結構

 核心部分: CPU、記憶體

1.CPU內部結構

  • 控制單元: 整個 CPU 的指揮控制中心
  • 運算單元: 運算器核心,執行算術運算與邏輯運算。運算器接收控制單元的指令而執行動作
  • 儲存單元: CPU 中暫時儲存資料的地方,包括 CPU 片內快取 Cache 和 暫存器組

1.1.CPU快取結構

現代 CPU 為了提升執行效率,減少 CPU 與記憶體的互動(互動影響 CPU 效率),一般在 CPU上整合了多級快取架構,常見的為三級快取結構

  • L1 Cache,分為資料快取和指令快取,邏輯核獨佔
  • L2 Cache,物理核獨佔,邏輯核共用
  • L3 Cache,所有物理核共用

此機器的三級快取架構如下圖:L1 Cache又分為兩種,指令儲存單元(存指令),和邏輯儲存單元(存邏輯)。理論上一臺機器可以有多個 CPU,由插槽決定,一個 CPU 又有多核,一個核又可以由多個邏輯處理器。

暫存器是 CPU 內部元件,讀寫速度非常快。 CPU 讀取資料只會從暫存器中去取,每個 CPU 都有一個獨有的暫存器,其他 CPU 無法存取。採用暫存器,可以減少 CPU 存取記憶體的次數,從而提高了 CPU 的工作速度。

越靠近 CPU 讀取速度越快,摩爾定律中,CPU 以每18個月翻一番的速度在發展,而記憶體和硬碟的發展速度遠遠跟不上。為了解決 CPU 運算速度和 IO 速度不匹配的問題,CPU 開始被內建了少量的快取記憶體 Lx Cache(CPU空間有限,儲存元件大小受限)。

  • 記憶體儲存空間大小: 記憶體 > L3 Cache > L2 Cache > L1 Cache > 暫存器
  • 記憶體讀取速度快慢: 暫存器 > L1 Cache > L2 Cache > L3 Cache > 記憶體
  • 快取是由最小的儲存區塊--- 快取行(CacheLine) 組成,快取行大小通常為64byte。我的機器L1的快取大小時512K,則由512 * 1024/64個快取行組成。

CPU讀取記憶體資料過程: CPU 僅能直接從暫存器中獲取資料。 假設資料 x = 0 在記憶體中,則它的取值過程如下:

判斷暫存器中是否存在

不存在則遍歷L1 Cache 看是否存在,不存在遍歷L2 Cache,L2 Cache 中沒有,遍歷L3 Cache。中間過程存在,則會把 Cache 行鎖住,拷貝到上一級,直至到暫存器。

Cache 中沒有則區記憶體中找,先通知記憶體控制器佔用匯流排頻寬,通知記憶體加鎖,發起記憶體讀請求,等待迴應,迴應資料拷貝到L3 Cache。 注意:整個過程加鎖直至到CPU才會解開

區域性性原理:在CPU存取儲存裝置時,無論是存取資料還是存取指令,都趨於聚集在一片連續的區域中。

這種區域性性原理又有兩種:

  • 時間區域性性(Temporal Locality): 如果一個資訊項正在被存取,那麼在近期它很可能還會被再次存取。 比如迴圈、遞迴、方法的反覆呼叫等。
  • 空間區域性性(Spatial Locality): 如果一個記憶體的位置被參照,那麼將來他附近的位置也會被參照。 比如順序執行的程式碼、連續建立的兩個物件、陣列等。

空間區域性性的例子: 一個很大的二維陣列,累加求和一行一行加會比一列一列累加快很多。在CPU 在記憶體中讀取資料時會將附件的資料都讀進去。

1.2.CPU執行安全等級

CPU被劃分為 4 個執行級別:

  •  ring0 核心態
  •  ring1
  •  ring2
  •  ring3 使用者態

Linux 和 Windows 都只用到了兩個級別:ring0ring3,作業系統內部內部程式指令通常執行在 ring0 級別,作業系統以外的第三方程式執行在 ring3 級別,第三方程式如果要呼叫作業系統內部函數功能,由於執行安全級別不夠,必須切換CPU執行狀態,從 ring3 切換到 ring0, 然後執行系統函數,建立執行緒,執行緒阻塞喚醒是重型操作,因為CPU要切換執行狀態。 

JVM 建立執行緒是 CPU 的流程:

  • 第一步:CPU 從 ring3 切換 ring0 建立執行緒
  • 第二步: 建立完畢,CPU從 ring0 切回 ring3
  • 第三步: 執行緒執行JVM程式
  • 第四步: 執行緒執行完畢,銷燬切回 ring0
  • 第五步: 執行緒銷燬,切回 ring3

2.作業系統記憶體管理

為了使程式執行安全隔離與穩定,作業系統有使用者空間核心空間兩個概念。以 32位元作業系統4G大小的記憶體空間為例:

Linux 為核心程式碼和資料結構預留了幾個頁框,這些頁永遠不會被轉出到磁碟上(4GB記憶體空間,使用者程式可使用3GB)。如圖綠色部分的線性地址可由使用者程式碼和核心程式碼進行參照(即使用者空間)。黃色部分的線性地址只能由核心程式碼進行存取(即核心空間)。

程序與執行緒只能執行在使用者方式(usermode) 或 核心方式(kernelmode) 下。使用者程式執行在使用者方式下,而系統呼叫執行在核心方式下。

使用者方式下使用一般的堆疊(使用者空間的堆疊),核心方式下使用固定大小的堆疊(核心空間的堆疊,一般為一個記憶體頁的大小),即每個程序與執行緒其實有兩個堆疊,分別執行與使用者態核心態

CPU排程的基本單位執行緒,也劃分為:

  • 核心執行緒模型(KLT): Java使用,核心儲存執行緒的狀態和上下文資訊,執行緒阻塞不會引起程序阻塞。在多處理器系統上,多執行緒在多處理器上並行執行。執行緒的建立、排程和管理由核心完成,效率比ULT要慢,比程序操作快。
  • 使用者執行緒模型(ULT): 不依賴作業系統核心,應用提供建立、同步、排程和管理執行緒的函數來控制使用者執行緒。不需要使用者態/核心態切換,速度快。核心對ULT無感知,執行緒阻塞則程序(包括它的所有執行緒)阻塞

 執行緒都有兩個堆疊,一個在使用者空間,一個在核心空間。阻塞、建立、殺死執行緒將拋棄使用者空間的堆疊,轉移到核心空間,執行完畢後再轉移到使用者空間。

3.程序與執行緒

程序: 作業系統資源分配的最小單位,例如:啟動一個 Java 程式,作業系統就會建立一個Java 程序,程序中可以包含多個執行緒。

執行緒: 作業系統排程CPU的最小單元,執行緒都擁有各自的計數器、堆疊和區域性變數等屬性, 並且能夠存取共用的記憶體變數。CPU 在這些執行緒上高速切換,讓使用者感覺到這些執行緒在同時執行(並行)。

執行緒上下切換: 儲存上一個執行緒執行的中間狀態,執行下一個執行緒

  • 序列: 時間上不可重疊,前一個任務沒完成,下一個任務只能等待
  • 並行: 時間上是重疊的,兩個任務在同一時刻互不干擾的同時執行
  • 並行: 執行兩個任務彼此干擾,同一時間點,只有一個任務執行,交替執行

到此這篇關於認識Java底層作業系統與並行基礎的文章就介紹到這了,更多相關Java底層作業系統內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com