現(xiàn)代計(jì)算機(jī)模型-J.U.C并發(fā)系列(1)

系列介紹

本系列主要重點(diǎn)介紹Java中的J.U.C并發(fā)編程,從原理,理論到實(shí)踐的過程,帶你一步步了解各種知識(shí)點(diǎn),把所有技術(shù)點(diǎn)構(gòu)成一個(gè)閉環(huán),形成一個(gè)知識(shí)體系。

希望在J.U.C系列對(duì)你有新的了解和認(rèn)知。

第一步,我想從計(jì)算機(jī)的底層模型來做為我這個(gè)系列的開頭,因?yàn)槟阒挥欣斫饬擞?jì)算機(jī)的原理和結(jié)構(gòu),才能對(duì)于Java的一些設(shè)計(jì)(J.U.C,Sync,JMM)才有更加深刻的理解和使用。

本章節(jié)不涉及到Java相關(guān)的知識(shí)點(diǎn)。

現(xiàn)代計(jì)算機(jī)理論模型

現(xiàn)代計(jì)算機(jī)模型是基于-馮諾依曼計(jì)算機(jī)模型

image.png

也稱馮·諾伊曼模型(Von Neumann model)或普林斯頓結(jié)構(gòu)(Princeton architecture),是一種將程序指令存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器合并在一起的計(jì)算機(jī)設(shè)計(jì)概念結(jié)構(gòu)。依據(jù)馮·諾伊曼結(jié)構(gòu)設(shè)計(jì)出的計(jì)算機(jī)稱做馮.諾依曼計(jì)算機(jī),又稱存儲(chǔ)程序計(jì)算機(jī)。

計(jì)算機(jī)在運(yùn)行指令時(shí),會(huì)從存儲(chǔ)器中一條條指令取出,通過譯碼(控制器),從存儲(chǔ)器中取出數(shù)據(jù),然后進(jìn)行指定的運(yùn)算和邏輯等操作,然后再按地址把運(yùn)算結(jié)果返回內(nèi)存中去。

接下來,再取出下一條指令,在控制器模塊中按照規(guī)定操作。依此進(jìn)行下去。直至遇到停止指令。

程序與數(shù)據(jù)一樣存貯,按程序編排的順序,一步一步地取出指令,自動(dòng)地完成指令規(guī)定的操作是計(jì)算機(jī)最基本的工作模型。這一原理最初是由美籍匈牙利數(shù)學(xué)家馮.諾依曼于1945年提出來的,故稱為馮.諾依曼計(jì)算機(jī)模型。

計(jì)算機(jī)五大核心組成部分

  • 控制器(Control):

    • 是整個(gè)計(jì)算機(jī)的中樞神經(jīng),其功能是對(duì)程序規(guī)定的控制信息進(jìn)行解
      釋,根據(jù)其要求進(jìn)行控制,調(diào)度程序、數(shù)據(jù)、地址,協(xié)調(diào)計(jì)算機(jī)各部分工作及內(nèi)存與外設(shè)的訪問等。
  • 運(yùn)算器(Datapath)

    • 運(yùn)算器的功能是對(duì)數(shù)據(jù)進(jìn)行各種算術(shù)運(yùn)算和邏輯運(yùn)算,即對(duì)數(shù)據(jù)進(jìn)
      行加工處理。
  • 存儲(chǔ)器(Memory)

    • 存儲(chǔ)器的功能是存儲(chǔ)程序、數(shù)據(jù)和各種信號(hào)、命令等信息,并在需
      要時(shí)提供這些信息。
  • 輸入(Input system)

    • 略,輸入設(shè)備有鍵盤、鼠標(biāo)器等。
  • 輸出(Output system)

    • 略。打印機(jī)等。
計(jì)算機(jī)模型

上圖為計(jì)算機(jī)模型流程圖

  • 計(jì)算器
    • 實(shí)際上就是CPU的工作
  • 存儲(chǔ)器
    • 計(jì)算器中的內(nèi)存(RAM)

上圖的重點(diǎn)只需要看中間的部分,本質(zhì)的邏輯就是CPU、存儲(chǔ)。CPU是如何存儲(chǔ)數(shù)據(jù),計(jì)算;CPU、存儲(chǔ)是如何交互通信的。

現(xiàn)代計(jì)算機(jī)硬件結(jié)構(gòu)原理

下圖為計(jì)算器硬件的結(jié)構(gòu)原理圖

未命名文件.png

拓展槽:指的內(nèi)存條。

我們可以把重點(diǎn)放到CPU,I/O總線,拓展槽上面,那為何結(jié)構(gòu)是這樣設(shè)計(jì)的?

無論是CPU、存儲(chǔ)器、或者我們的計(jì)算器中的顯示器、鼠標(biāo)、鍵盤都是通過I/O總線來做交互通信。

I/O總線可以理解為一條高速通道,在這其中,CPU的頻率最高的達(dá)到GHz,而內(nèi)存條頻率遠(yuǎn)遠(yuǎn)無法和CPU相比擬,而玩過游戲的小伙伴也知道,對(duì)計(jì)算器的顯存也是會(huì)在I/O總線上面做通信,如此之多的模塊都在這上面,而CPU又是極高的頻率。

所以CPU的結(jié)構(gòu)原理就會(huì)有一個(gè)CPU Cache的設(shè)計(jì),就是會(huì)把收到的指令復(fù)制一遍存到CPU Cache中,進(jìn)行計(jì)算。
運(yùn)行速度來對(duì)比的:寄存器 > L1 > L2 > L3 > 內(nèi)存條,而內(nèi)存條的讀寫速率遠(yuǎn)遠(yuǎn)小于CPU Cache,所以這個(gè)也是會(huì)有CPU Cache的設(shè)計(jì)產(chǎn)生的原因之一。

因?yàn)閮?nèi)存條的頻率遠(yuǎn)遠(yuǎn)小于CPU,所以才會(huì)有了CPU Cache的出現(xiàn),內(nèi)存條把編譯后的指令,通過I/O總線放到CPU Cache中,進(jìn)行計(jì)算和存儲(chǔ)。

CPU

未命名文件 (1).png

CPU內(nèi)部結(jié)構(gòu)劃分,主要有三種類型的單元

  • 控制單元

    • 控制單元是整個(gè)CPU的指揮控制中心,由指令寄存器IR(Instruction Register)、指令譯碼器ID(Instruction Decoder)和 操作控制器OC(Operation Controller) 等組成,對(duì)協(xié)調(diào)整個(gè)電腦有序工作極為重要。它根據(jù)用戶預(yù)先編好的程序,依次從存儲(chǔ)器中取出各條指
      令,放在指令寄存器IR中,通過指令譯碼(分析)確定應(yīng)該進(jìn)行什么操作,然后通過操作控制器OC,按確定的時(shí)序,向相應(yīng)的部件發(fā)出微操作控制信號(hào)。操作控制器OC中主要包括:節(jié)拍脈沖發(fā)生器、控制矩陣、時(shí)鐘脈沖發(fā)生器、復(fù)位電路和啟停電路等控制邏輯。
  • 運(yùn)算單元

    • 運(yùn)算單元是運(yùn)算器的核心??梢詧?zhí)行算術(shù)運(yùn)算(包括加減乘數(shù)等基本運(yùn)算及其附加運(yùn)算)和邏輯運(yùn)算(包括移位、邏輯測(cè)試或兩個(gè)值比較)。相對(duì)控制單元而言,運(yùn)算器接受控制單元的命令而進(jìn)行動(dòng)作,即運(yùn)算單元所進(jìn)行的全部操作都是由控制單元發(fā)出的控制信號(hào)來指揮的,所以它是執(zhí)行部件。
  • 存儲(chǔ)單元

    • 存儲(chǔ)單元包括 CPU 片內(nèi)緩存Cache和寄存器組,是 CPU 中暫時(shí)存放數(shù)據(jù)的地方,里面保存著那些等待處理的數(shù)據(jù),或已經(jīng)處理過的數(shù)據(jù),CPU 訪問寄存器所用的時(shí)間要比訪問內(nèi)存的時(shí)間短。 寄存器是CPU內(nèi)部的元件,寄存器擁有非常高的讀寫速度,所以在寄存器之間的數(shù)據(jù)傳送非???。采用寄存器,可以減少 CPU 訪問內(nèi)存的次數(shù),從而提高了 CPU 的工作速度。寄存器組可分為專用寄存器和通用寄存器。專用寄存器的作用是固定的,分別寄存相應(yīng)的數(shù)據(jù);而通用寄存器用。

CPU寄存器

每個(gè)CPU都包含一系列的寄存器,它們是CPU內(nèi)內(nèi)存的基礎(chǔ)。CPU在寄存器上執(zhí)行操作的速度遠(yuǎn)大于在主存上執(zhí)行的速度。這是因?yàn)镃PU訪問寄存器的速度遠(yuǎn)大于主存。

CPU緩存

即高速緩沖存儲(chǔ)器,是位于CPU與主內(nèi)存間的一種容量較小但速度很高的存儲(chǔ)器。由于CPU的速度遠(yuǎn)高于主內(nèi)存,CPU直接從內(nèi)存中存取數(shù)據(jù)要等待一定時(shí)間周期,Cache中保存著CPU剛用過或循環(huán)使用的一部分?jǐn)?shù)據(jù),當(dāng)CPU再次使用該部分?jǐn)?shù)據(jù)時(shí)可從Cache中直接調(diào)用,減少CPU的等待時(shí)間,提高了系統(tǒng)的效率。

內(nèi)存

一個(gè)計(jì)算機(jī)還包含一個(gè)主存。所有的CPU都可以訪問主存。主存通常比CPU中的緩存大得多。、

上面的圖,指的是內(nèi)存是如何和CPU進(jìn)行交互工作的,我們大概知道這個(gè)內(nèi)存結(jié)構(gòu)就可以了,希望幫助大家了解一下整體的結(jié)構(gòu),了解計(jì)算機(jī)是這樣的工作方式的,達(dá)成一個(gè)認(rèn)知即可。

問題舉例1

    public static void main(String[] args) {
        int i = 0;
        i = 1 + 1;
        System.out.println(i);
    }

假如執(zhí)行命令的main方法的時(shí)候,CPU、內(nèi)存會(huì)按照如下的流程進(jìn)行讀取存儲(chǔ)

1 . 初始化忽略,從 i = 1 + 1,開始,內(nèi)存會(huì)把這條指令發(fā)送到CPU中

  1. CPU寄存器會(huì)去讀?。╨oad)i的內(nèi)存地址,然后交由ALU進(jìn)行計(jì)算,計(jì)算結(jié)果(i=2)會(huì)以此緩存到L1,L2,L3;
  2. CPU會(huì)在空閑的時(shí)候再把結(jié)果同步到內(nèi)存到,不會(huì)立馬同步到內(nèi)存中,同步的條件,只有在自身的緩存內(nèi)存空間不足,才會(huì)進(jìn)行寫入同步到內(nèi)存中,那有沒有什么辦法可以把結(jié)果硬性的同步到內(nèi)存中?
    這里先引申出一個(gè)概念 : MESI緩存一致性協(xié)議

CPU多核緩存架構(gòu)

image.png

問題舉例2

有兩個(gè)線程T1,T2分別到CPU1,CPU2去執(zhí)行,執(zhí)行以下代碼方法

    private static int i = 0;
    public static void main(String[] args) {
        i +=1;
        System.out.println(i);
    }

按照上面的結(jié)構(gòu),每個(gè)CPU都是獨(dú)立,并且每個(gè)線程都保持有自己的對(duì)于i的一個(gè)副本,也就是i + 1,每個(gè)CPU在回寫同步數(shù)據(jù)結(jié)果的時(shí)候,并不知道其他的CPU也在針對(duì)i的內(nèi)存地址的結(jié)果進(jìn)行計(jì)算回寫,所以有可能有出現(xiàn)計(jì)算錯(cuò)誤。

當(dāng)各自的線程在CPU執(zhí)行完指令之后,實(shí)際的結(jié)果并非是 i + 1(T1) + 1(T2)的結(jié)果,有可能是 i = 2,這個(gè)就會(huì)出現(xiàn)我們的數(shù)據(jù)一致性問題。

緩存一致性問題
image.png

在多處理器系統(tǒng)中,每個(gè)處理器都有自己的高速緩存,而它們又共享同一主內(nèi)存(MainMemory)?;诟咚倬彺娴拇鎯?chǔ)交互很好地解決了處理器與內(nèi)存的速度矛盾,但是也引入了新的問題:緩存一致性(CacheCoherence)。當(dāng)多個(gè)處理器的運(yùn)算任務(wù)都涉及同一塊主內(nèi)存區(qū)域時(shí),將可能導(dǎo)致各自的緩存數(shù)據(jù)不一致的情況,如果真的發(fā)生這種情況,那同步回到主內(nèi)存時(shí)以誰的緩存數(shù)據(jù)為準(zhǔn)呢?為了解決一致性的問題,需要各個(gè)處理器訪問緩存時(shí)都遵循一些協(xié)議,在讀寫時(shí)要根據(jù)協(xié)議來進(jìn)行操作,這類協(xié)議有MSI、MESI(IllinoisProtocol)、MOSI、Synapse、Firefly及DragonProtocol,等等。

總線加鎖(奔騰處理器)這個(gè)是很早之前的一個(gè)CPU的實(shí)現(xiàn)方法,這個(gè)的原理就是每次CPU要把數(shù)據(jù)回寫到內(nèi)存中的時(shí)候,都需要去總線中獲取一個(gè)鎖,獲取鎖之后才可能把數(shù)據(jù)寫入到內(nèi)存中。而沒有獲取到鎖的CPU就需要等待,直到獲取鎖為止。

MESI協(xié)議

Cache line : Cache中最小緩存單位

  • M

    • 狀態(tài):修改
    • 描述 : 該Cache line有效,數(shù)據(jù)被修改了,和內(nèi)存中的數(shù)據(jù)不一致,數(shù)據(jù)只存在于本Cache中。
    • 監(jiān)聽任務(wù): Cache line 必須時(shí)刻監(jiān)聽所有試圖讀該Cache line 相對(duì)就內(nèi)存的操作,這種操作必須在緩存將Cache line寫回主內(nèi)存并將狀態(tài)變成S(共享)狀態(tài)之前被延遲執(zhí)行。
  • E

    • 狀態(tài):共享(Shared)
    • 描述 : 該Cache line有效,數(shù)據(jù)和內(nèi)存中的數(shù)據(jù)一致,數(shù)據(jù)存在于很多的Cache中
    • 監(jiān)聽任務(wù): Cache line 必須監(jiān)聽其他緩存使該Cache line無效或者獨(dú)享該Cache line的請(qǐng)求,并將該Cache line更換狀態(tài)為無效(Invaild)。
  • I

    • 狀態(tài):無效(Invaild)
    • 描述 : 該Cache line無效,無法做任何操作,不能回寫數(shù)據(jù)到主內(nèi)存中。
    • 監(jiān)聽任務(wù): 無

CPU Cache line會(huì)時(shí)時(shí)刻刻的去嗅探 BUS(緩存一致性協(xié)議),監(jiān)聽是否有新的狀態(tài)改變,是否有新的指令(#LOCK等),以此來改變自身的Cache Line的狀態(tài),以便后續(xù)可以做相應(yīng)的操作。

問題舉例2-解決

  1. T1會(huì)從主內(nèi)存load到指令到CPU1中,然后會(huì)把對(duì)應(yīng)的Cache line狀態(tài)變成S(獨(dú)占)狀態(tài);
  2. T2也執(zhí)行同樣操作,因?yàn)橛?個(gè)CPU獲取了同一個(gè)主內(nèi)存的數(shù)據(jù),所以T2的Cache line 會(huì)變成一個(gè)S(Shared)狀態(tài),T1中的Cache line會(huì)從 S(獨(dú)占) --> E(共享)進(jìn)行轉(zhuǎn)變。
  3. T1,T2會(huì)以此的把指令從L3到L2到L1再到寄存器,進(jìn)行計(jì)算,然后回寫到L3中,因?yàn)閷?duì)數(shù)據(jù)進(jìn)行修改,T1中的CPU需要對(duì)Cache line 進(jìn)行 鎖定操作,鎖定完成之后把狀態(tài)更改為M(修改)狀態(tài),此時(shí)(i = 2 );當(dāng)然T2也可以同時(shí)進(jìn)行修改狀態(tài)為 M(狀態(tài)),具體看誰快,CPU彼此之間也是有時(shí)間延遲存在。
  4. 當(dāng)T1更改完成狀態(tài)之后,以此同時(shí)會(huì)發(fā)送一個(gè)消息到BUS(緩存一致性協(xié)議)中,通知其他的監(jiān)聽該內(nèi)存的Cache line。
  5. 此時(shí),CPU會(huì)有一個(gè)指令周期,去進(jìn)行裁決Cache line的狀態(tài)。T2的Cache line監(jiān)聽到了數(shù)據(jù)變化(i = 2 ),會(huì)把自身的狀態(tài)更新為 I(Invaild)狀態(tài),無法再更新數(shù)據(jù)(T2 i = 2)到主內(nèi)存中。
  6. 假如T2還想再更新數(shù)據(jù)到主內(nèi)存中,需要重新的從主內(nèi)存中l(wèi)oad數(shù)據(jù)(i = 2)到CPU中,再重新計(jì)算ALU,然后回寫到主內(nèi)存中(i = 2 + 1)

Cache line 狀態(tài)失效場(chǎng)景

  1. 當(dāng)i存儲(chǔ)長(zhǎng)度大于一個(gè)Cache line的時(shí)候,這個(gè)時(shí)候需要存儲(chǔ)到多個(gè)Cache line,這個(gè)時(shí)候是無法做到MESI緩存一致性協(xié)議的,只能用總線鎖。
  2. 當(dāng)CPU不支持MESI

小結(jié)

回顧本章,我們了解到了計(jì)算機(jī)的模型,CPU,內(nèi)存的交互通信工作流程,以及如何保證緩存一致性(MESI)等知識(shí)點(diǎn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容