偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

馮諾依曼結(jié)構(gòu)?什么是內(nèi)存(存儲(chǔ)器層次結(jié)構(gòu))

存儲(chǔ) 存儲(chǔ)軟件
我們先來討論:計(jì)算機(jī)的運(yùn)行究竟是在做什么?來看一下經(jīng)典的馮諾依曼結(jié)構(gòu)。計(jì)算機(jī)科學(xué)雖然飛速發(fā)展了幾十年,但是依舊遵循馮諾依曼結(jié)構(gòu)。

 [[253378]]

我們先來討論:計(jì)算機(jī)的運(yùn)行究竟是在做什么?來看一下經(jīng)典的馮諾依曼結(jié)構(gòu)。計(jì)算機(jī)科學(xué)雖然飛速發(fā)展了幾十年,但是依舊遵循馮諾依曼結(jié)構(gòu)。

馮諾依曼結(jié)構(gòu)

 

數(shù)學(xué)家馮諾依曼提出的 體系結(jié)構(gòu)包含以下幾個(gè)要點(diǎn):

  • 把程序本身當(dāng)作數(shù)據(jù)來對(duì)待,程序和該程序處理的數(shù)據(jù)用同樣的方式儲(chǔ)存。
  • 計(jì)算機(jī)的數(shù)制采用二進(jìn)制。
  • 計(jì)算機(jī)應(yīng)該按照程序順序執(zhí)行。

我們根據(jù)這張圖進(jìn)行思考就可以得到一個(gè)結(jié)論,所謂計(jì)算機(jī)處理任務(wù),就是根據(jù)輸入內(nèi)容,數(shù)據(jù)/程序從存儲(chǔ)器送往CPU進(jìn)行處理,然后再將結(jié)果輸出。

關(guān)于程序與數(shù)據(jù),數(shù)據(jù)就是一首MP3歌曲, 程序就是用來控制解析播放這首歌的代碼,從底層來講就是供CPU運(yùn)行的指令.總之在計(jì)算機(jī)當(dāng)中它們都是0和1,不過為行文方便,我們直接簡(jiǎn)稱為數(shù)據(jù)或程序或指令, 將它們理解為同一個(gè)意思,畢竟它們都屬于0和1組成的流,這個(gè)可以根據(jù)上下文來理解。

本文討論的主要內(nèi)容,就是 存儲(chǔ)器部分,為什么計(jì)算機(jī)需要存儲(chǔ)器部分?這是顯而易見的,我寫好了程序,或者下載了一部電影,肯定得有個(gè)地方放啊。這樣今后需要的時(shí)候,才能運(yùn)行程序或者看電影啊。

我們思考一下,這個(gè)存儲(chǔ)器應(yīng)該具備什么樣的特點(diǎn)。

  • 1.穩(wěn)定,掉電不丟失數(shù)據(jù):這個(gè)道理上面已經(jīng)提過,辛辛苦苦下載個(gè)小電影,一關(guān)電腦數(shù)據(jù)都丟失了。這肯定不行的。
  • 2.存儲(chǔ)容量大:就像誰也不嫌棄自己錢多,嫌棄自家房子太大。我們既然存儲(chǔ)東西,那么容量肯定越大越好。
  • 3.讀寫速度快:拷貝個(gè)電視劇,速度那么慢,真心累啊。
  • 4.價(jià)格便宜:新發(fā)布的iphone x我為啥不買,因?yàn)樗幸粋€(gè)缺點(diǎn)我無法接受,那就是太貴了。一臺(tái)電腦賣一百萬,我們誰又能買得起呢?
  • 5.體積?。哼@個(gè)也是理所當(dāng)然的。

關(guān)于這個(gè)存儲(chǔ)器,我們大概想出了一個(gè)理想的存儲(chǔ)器應(yīng)該具備的的5個(gè)特點(diǎn)。

但是有句話說的好。理想很豐滿,顯示很骨感。一個(gè)屌絲在紙上列出了幾十條他理想女友的標(biāo)準(zhǔn),但是他能如愿嗎?

先說結(jié)論,完全滿足我們理想條件的存儲(chǔ)器目前還沒發(fā)明出來呢。目前的半導(dǎo)體工業(yè)只能造出部分符合條件的存儲(chǔ)器,但是完全滿足以上幾條標(biāo)準(zhǔn)的,對(duì)不起,未來也許能做到,但是起碼目前做不到。

所以這也是目前計(jì)算機(jī)系統(tǒng)存儲(chǔ)器系統(tǒng)比較復(fù)雜的原因,區(qū)分為內(nèi)存,硬盤,光盤等不同的存儲(chǔ)器,如果有個(gè)完美的符合我們理想條件的存儲(chǔ)器,直接使用這種存儲(chǔ)器就好了。

先看看看我們最常見的存儲(chǔ)設(shè)備:磁盤。足夠穩(wěn)定;有電沒電都正常存儲(chǔ);容量也較大;價(jià)格也可以接受,所以磁盤是我們最常見的存儲(chǔ)設(shè)備。

磁盤就是我們存儲(chǔ)器的代表了。

為了行文方便,文中直接將存儲(chǔ)器用磁盤來代替了,一來大家對(duì)磁盤比較熟悉,二來磁盤也是最常見的存儲(chǔ)設(shè)備。類似flash,SD卡,ROM等從廣義上來講,也可以稱為磁盤。因?yàn)樗鼈兊淖饔枚际谴鎯?chǔ)數(shù)據(jù),掉電后不丟失。(這在下面文章中也會(huì)討論到)

磁盤和硬盤什么關(guān)系呢?其實(shí)是同一個(gè)意思。硬盤是最常見的磁盤類型。在很早之前,計(jì)算機(jī)使用軟盤存儲(chǔ)數(shù)據(jù),所以那種軟盤也被稱為 磁盤,不過軟盤都早就被歷史淘汰了,(電腦硬盤分區(qū)從C盤開始,就是因?yàn)锳B盤是之前軟盤的編號(hào))。所以現(xiàn)在我們說磁盤,直接理解成硬盤就好了。

在我們軟件當(dāng)中,有個(gè)概念叫做數(shù)據(jù)持久化,意思就是說將數(shù)據(jù)存儲(chǔ)起來,掉電之后不丟失,這其實(shí)就是存儲(chǔ)在磁盤上面。

所以現(xiàn)在我們理解的計(jì)算機(jī)運(yùn)行就是這樣一個(gè)過程:將數(shù)據(jù)從磁盤送往CPU,供CPU進(jìn)行計(jì)算,并將結(jié)果輸出。

因?yàn)槲覀冞@片文章就是 討論 內(nèi)存,存儲(chǔ)等問題,所以關(guān)于 輸入設(shè)備,輸出設(shè)備之類的,就不再涉及和討論。

然后我們?cè)俸?jiǎn)短來討論CPU的發(fā)展歷史。

世界上第一臺(tái)計(jì)算機(jī)是1946年在美國(guó)誕生的ENIAC,當(dāng)時(shí)CPU還是使用笨重的電子管,后面的故事依次是貝爾實(shí)驗(yàn)室發(fā)明了晶體管,TI的工程師又發(fā)明了集成晶體管,IBM研發(fā)成功首款使用集成電路的計(jì)算機(jī),IBM360, 后面 就是仙童八叛徒與intel,AMD的故事了。這段很著名的IT故事,我們不再累述了。伴隨著世界上第一款商用處理器:Intel4004的出現(xiàn),波瀾壯闊的摩爾定律開始了。

當(dāng)時(shí)負(fù)責(zé)IBM 360 操作系統(tǒng)開發(fā)的那個(gè)項(xiàng)目經(jīng)理,根據(jù)該項(xiàng)目經(jīng)驗(yàn), 寫了一本經(jīng)典著作《人月神話》,也有其他參與者根據(jù)該項(xiàng)目經(jīng)驗(yàn),立傳出書了,所以當(dāng)時(shí)那批人都是大牛。

摩爾定律:當(dāng)價(jià)格不變時(shí),集成電路上可容納的元器件的數(shù)目,約每隔18-24個(gè)月便會(huì)增加一倍,性能也將提升一倍。

半導(dǎo)體行業(yè)開始騰飛了。CPU上集成的晶體管數(shù)量越來越多。 intel i9的制程工藝已經(jīng)到了14nm。所以CPU的執(zhí)行速度也越來越快。

當(dāng)然,摩爾定律也快到盡頭了,根據(jù)量子力學(xué),2nm是理論極限值。線寬不能再細(xì)了,低于2nm,隧穿效應(yīng)就會(huì)產(chǎn)生干擾。

閑扯了一段CPU的發(fā)展歷史,想說明的是,現(xiàn)在的CPU集成度越來越高,速度也越來越快。每秒鐘能執(zhí)行的指令也越來越多。(如果不知道指令,匯編之類的啥意思,看一下我的的另一篇文章關(guān)于跨平臺(tái)的一些認(rèn)識(shí),否則下面的內(nèi)容看著也有難度)。

CPU的作用就是去執(zhí)行指令(當(dāng)然,也包括輸出結(jié)果等,本文只討論和存儲(chǔ)器相關(guān),所以不扯其他的),并且盡可能的以它的極限最高速度去執(zhí)行指令,至于具體的執(zhí)行過程,做過單片機(jī)或者學(xué)過微機(jī)原理的應(yīng)該比較清楚。就是伴隨著時(shí)鐘周期滴滴答答的節(jié)奏,CPU踏著拍子來執(zhí)行指令。

至于CPU的指令集,那就是Intel的架構(gòu)師們的工作,總之,CPU認(rèn)識(shí)這些指令,并且能執(zhí)行運(yùn)算。(別忘記了馮諾依曼體系結(jié)構(gòu)那張圖)。對(duì)于這些指令,但是CPU采取了各種措施來加快執(zhí)行過程(也可以理解為加快它的計(jì)算速度)。比如有以下幾種常見的措施:

  • 流水線(pipeline)技術(shù):有電子廠打工經(jīng)歷的讀者肯定很熟悉這個(gè)流水線模式。CPU的流水線工作方式和工業(yè)生產(chǎn)上的流水線概念一樣。就是將一個(gè)指令的執(zhí)行過程也分解為多個(gè)步驟,CPU中的每個(gè)電路只執(zhí)行其中一個(gè)步驟,這樣前赴后繼加快執(zhí)行速度。CPU中多個(gè)不同功能的電路單元組成一條指令處理流水線,然后將一條指令分成幾個(gè)步驟后再由這些電路單元分別執(zhí)行。在執(zhí)行過程中,指令源源不斷的送往CPU。讓每個(gè)電路單元都不閑著,這樣就大大的加快了執(zhí)行速度。
  • 超線程(Hyper-Threading)技術(shù):對(duì)于超線程,百度百科的解釋我都沒看懂,但是大概原理就是這樣的。CPU在進(jìn)行線程切換的時(shí)候,要執(zhí)行 切換各種寄存器狀態(tài)等一些操作。把第一個(gè)線程的各種寄存器狀態(tài)寫回緩存中保存,然后把第二個(gè)線程的相關(guān)內(nèi)容送到各種寄存器上。該過程必不可少,否則待會(huì)再將第一個(gè)線程切換回來時(shí),不知道該線程的各個(gè)狀態(tài), 那還怎么接著繼續(xù)執(zhí)行呢?也正因?yàn)槿绱?,所以這個(gè)過程比較慢,大概需要幾萬個(gè)時(shí)鐘周期。所以后來做了這樣的設(shè)計(jì),把每個(gè)寄存器等都多做一個(gè),就是多做一組寄存器(也包括一些其他相關(guān)電路等),,CPU在執(zhí)行A線程時(shí),使用的第一組寄存器,切換到B線程,直接使用第二組寄存器,然后再切換A線程時(shí),再使用第一組寄存器。,CPU就不用再傻傻的等著寄存器值的切換,線程切換只需要幾個(gè)時(shí)鐘周期就夠了。對(duì)于普通的執(zhí)行多任務(wù)的計(jì)算機(jī),CPU線程切換是個(gè)非常頻繁的操作,所以使用該技術(shù)就會(huì)節(jié)省大量的時(shí)鐘周期。也就是相當(dāng)于加快了CPU的執(zhí)行速度。這就是CPU宣傳參數(shù)中所謂的四核八線程的由來,其實(shí)就是超線程技術(shù)。(每個(gè)核多做一組寄存器等電路固然會(huì)占用寶貴的空間,但是它帶來的優(yōu)點(diǎn)遠(yuǎn)遠(yuǎn)大于缺點(diǎn))。
  • 超標(biāo)量技術(shù):CPU可以在每個(gè)時(shí)鐘周期內(nèi)執(zhí)行多個(gè)操作,可以實(shí)行指令的并行運(yùn)算。
  • 亂序執(zhí)行: 我們認(rèn)為程序都是順序執(zhí)行的。但是在CPU層面上,指令的執(zhí)行順序并不一定與它們?cè)跈C(jī)器級(jí)程序(匯編)中的順序一樣。比如 a = b+c; d++;這兩個(gè)語句 不按照順序執(zhí)行也不會(huì)影響最終結(jié)果。當(dāng)然這只是在CPU執(zhí)行指令的層面,在程序員們看來,依舊認(rèn)為程序是順序執(zhí)行的。

前面扯了那么多,就是為了說明CPU的執(zhí)行速度很快。雖然每條指令的執(zhí)行時(shí)間需要幾個(gè)時(shí)鐘周期到幾十個(gè)時(shí)鐘周期不等。但是CPU采用了種種技術(shù)來加快執(zhí)行過程。所以平均執(zhí)行一條指令只需要一個(gè)周期。而現(xiàn)在CPU主頻都那么高。比如i7 7700K主頻達(dá)到了 4.2G。這也就意味著,每個(gè)core每秒鐘大約可以執(zhí)行4.2億條指令。那四個(gè)core呢?

CPU每秒鐘可以執(zhí)行幾億(甚至十幾億)條指令,所以它的執(zhí)行速度真丫的的快啊

我們討論完CPU如此快的執(zhí)行速度,我們?cè)賮碚f我們常見的存儲(chǔ)設(shè)備-機(jī)械硬盤。

 

圖2:機(jī)械硬盤結(jié)構(gòu)

機(jī)械硬盤的結(jié)構(gòu)就不再具體的討論了。它讓我想起了民國(guó)電影中那種播放音樂的唱片機(jī)。

帶機(jī)械硬盤的電腦,在使用過程中,如果機(jī)箱被摔了,可能后果很嚴(yán)重,就是因?yàn)榭赡軙?huì)把機(jī)械硬盤的那個(gè)讀寫頭/傳動(dòng)臂等機(jī)械結(jié)構(gòu)摔壞。

機(jī)械硬盤容量很大(目前普遍1T,2T),我們的數(shù)據(jù)和程序是存儲(chǔ)在磁盤上的,所以CPU要想執(zhí)行指令/數(shù)據(jù),就要從存儲(chǔ)器,也就是磁盤上讀取, CPU一秒鐘可以執(zhí)行幾億條指令,但是相對(duì)之下,磁盤的讀寫速度就是慢如蝸牛。假設(shè)磁盤一秒鐘可以讀取100條指令。那么這中間就存在 巨大的速度差異。半導(dǎo)體行業(yè)發(fā)展了幾十年,CPU的執(zhí)行速度一再飛速提升,奈何磁盤技術(shù)發(fā)展的太不給力了,CPU再快,可是磁盤嚴(yán)重拖后腿,那CPU就相當(dāng)于工作嚴(yán)重不飽和,如果直接從磁盤上 來讀取數(shù)據(jù),那么CPU相當(dāng)于 99.9999%的時(shí)間都在閑置著。

"假設(shè)磁盤一秒鐘可以讀取100條指令。":帶有假設(shè)字樣的,具體數(shù)字都是隨便寫的。比如 磁盤讀寫速度自然有它的參數(shù)指標(biāo),不過我們只是為了說明問題, 所以能理解其中的道理就好。

磁盤廠商們也在努力研究,比如SSD(固態(tài)硬盤),它的速度就比 機(jī)械硬盤快了一二十倍吧。但是對(duì)于CPU的速度,這也是然并卵啊。(更何況SSD相比機(jī)械硬盤太貴了)

所以這就是個(gè)大問題。

我們的目標(biāo)就是執(zhí)行任務(wù)時(shí)讓CPU全負(fù)荷的運(yùn)行,爭(zhēng)取對(duì)于每一個(gè)時(shí)鐘周期,CPU都不會(huì)閑置浪費(fèi)。

這就像是老板對(duì)我們這些員工的希望一樣。老板給我們發(fā)工資, 那么他就是希望我們每一天的每一分每一秒都在努力幫公司干活。不要有什么任何時(shí)間閑著。所以我們要感謝勞動(dòng)法,讓我們每天工作八小時(shí)就夠了。畢竟我們也是血肉之軀,也需要吃喝拉撒睡覺。

看到勞動(dòng)法說每天工作八小時(shí)就夠了,程序猿們哭暈在廁所。

程序猿問科比:“你為什么這么成功? ”

科比:“你知道洛杉磯凌晨四點(diǎn)是什么樣子嗎? ”

程序猿:“不知道,一般那個(gè)時(shí)候我還沒下班呢,怎么了?”

科比:“額…….”

通過上面的介紹,我們就明白了計(jì)算機(jī)體系的主要矛盾,CPU太快了,而磁盤太慢了。所以它倆是不能夠直接通信的,我們可以加一層過度。這就是內(nèi)存的作用。這就是幾百塊錢一根的內(nèi)存條的作用和功能。

實(shí)際上,一般情況下,內(nèi)存的讀寫速度比磁盤快幾十萬倍左右。所以它終于夠資格和CPU直接通信了。

這里有張圖,我們來看一下磁盤/內(nèi)存,與CPU速度之間逐漸增大的差距(主要是CPU技術(shù)發(fā)展太迅猛了)。

 

圖三:磁盤DRAM和cpu速度之間逐漸增大的差距

所以現(xiàn)在程序執(zhí)行過程是這樣的。CPU執(zhí)行任務(wù)時(shí),只與內(nèi)存通信,它從內(nèi)存獲取指令/數(shù)據(jù)或?qū)懟財(cái)?shù)據(jù)。內(nèi)存再與磁盤通信,內(nèi)存從磁盤讀取數(shù)據(jù)/指令,或者內(nèi)存將數(shù)據(jù)寫回磁盤。

提到添加過渡層。這其實(shí)和JVM的原理都是類似的。具體可參考我的另一篇文章關(guān)于跨平臺(tái)的一些認(rèn)識(shí)。也許這就是大道至簡(jiǎn)吧。

存儲(chǔ)器層次結(jié)構(gòu)

我們這里說的內(nèi)存,主要是指主存。就是主板上插的內(nèi)存條。它的讀寫速度比磁盤快了幾十萬倍。但是相對(duì)于CPU的速度依舊還是慢。那么主存和CPU之間,可以繼續(xù)添加速度更快的過度層。所以intel i7的存儲(chǔ)器層次結(jié)構(gòu)是這樣的。

 

圖4:一個(gè)存儲(chǔ)器層次結(jié)構(gòu)的示例

前面扯了那么多篇幅,就是告訴你,我們?yōu)槭裁葱枰獌?nèi)存(主存),那么理解了主存,自然也就理解了L3,L2,L1等各級(jí)緩存存在的意義。對(duì)于現(xiàn)代的計(jì)算機(jī)系統(tǒng),在CPU與磁盤/主存之間,加了多層過度層。

嚴(yán)格來講,應(yīng)該叫CPU的算術(shù)邏輯單元(ALU),但是簡(jiǎn)單的直接說CPU,大家肯定也能聽得懂。

實(shí)際上這是一種緩存思想。比如,本地磁盤也相當(dāng)于 遠(yuǎn)方服務(wù)器的緩存。因?yàn)槲覀儚木W(wǎng)上下載數(shù)據(jù)/文件時(shí),速度明顯比從本地磁盤讀取要慢。

一般情況下,L5磁盤與L4主存速度相差幾十萬倍, 而L3-L0之間,它們每級(jí)緩存的速度差異大概是10倍。

我們是拿i7處理器來做例子,它有三級(jí)緩存,像低端一些的處理器,比如i3,只有兩級(jí)緩存,但是道理是相同的。本文當(dāng)中,都是拿i7的存儲(chǔ)器層次來做例子。

明白一點(diǎn)。CPU執(zhí)行速度實(shí)在太快了,一秒鐘執(zhí)行幾億/十幾億條指令,CPU干活干脆利落,那么存儲(chǔ)器就要想方設(shè)法的用最快的速度把指令/數(shù)據(jù) 送給CPU去運(yùn)行。否則CPU干活再快,又有什么意義呢。

基本思想已經(jīng)理解了。那么我們就開始具體討論細(xì)節(jié)問題。

RAM,ROM,總線等

看看上面那幅圖,什么SRAM,DRAM,還有我們前面講的SSD,F(xiàn)lash,機(jī)械硬盤等,還有下面要討論的總線(BUS),所以我們先來討論一些基礎(chǔ)硬件知識(shí).

首先,他們都屬于存儲(chǔ)器,存儲(chǔ)器分為兩類:

  • 易失性(volatile)存儲(chǔ)器:包括內(nèi)存,SRAM,DRAM等,特點(diǎn)是讀寫速度很快,掉電了數(shù)據(jù)會(huì)丟失,價(jià)格貴,并且存儲(chǔ)容量較小。
  • 非易失性(nonvolatile)存儲(chǔ)器:包括磁盤,F(xiàn)lash,光盤,機(jī)械硬盤,SSD等,與易失性存儲(chǔ)器相比,它們讀寫速度很慢,但是掉電不丟失數(shù)據(jù),存儲(chǔ)容量比較大,價(jià)格也便宜。
  • RAM(Random-Access Memory):隨機(jī)訪問存儲(chǔ)器。易失性存儲(chǔ)器。也可以訪問兩類:SRAM(靜態(tài)的)和DRAM(動(dòng)態(tài)的),并且SRAM的讀寫速度比DRAM更快,價(jià)格也更貴。在上圖中也可以看到, SRAM做L1-L3級(jí)緩存,而DRAM做L4級(jí)的主存。
  • ROM(read-only memory):只讀存儲(chǔ)器,非易失性存儲(chǔ)器。這個(gè)名字容易讓人產(chǎn)生誤解,它既可以讀,也可以寫,稱之為read-only只是歷史原因。

ROM相比于RAM,容量更大,價(jià)格便宜,讀寫速度則比較慢。

  • 閃存(Flash memory):非易失性存儲(chǔ)器。SSD,SD卡都屬于Flash技術(shù),如果從概念上來講,他們都屬于ROM,這類存儲(chǔ)器經(jīng)常用在手機(jī),相機(jī)等設(shè)備上。而機(jī)械硬盤常用在個(gè)人計(jì)算機(jī),服務(wù)器上。

其實(shí)我覺的把 Flash,ROM等都叫做磁盤,也沒什么錯(cuò)。畢竟它們的作用和概念都是相似的,區(qū)別只是他們各自使用的半導(dǎo)體技術(shù)不同。Flash芯片等基于集成芯片的存儲(chǔ)器讀寫速度比機(jī)械硬盤快,不過(相同容量下)價(jià)格也比后者貴。而它們相比于SRAM,DRAM則非常慢了,所以后者理解為內(nèi)存即可。

"圖4:一個(gè)存儲(chǔ)器層次結(jié)構(gòu)的示例",越往上,讀寫速度越快,價(jià)格更貴,存儲(chǔ)容量也越小。(淘寶上搜搜8G的內(nèi)存條,256G的SSD,1T的機(jī)械硬盤都是什么價(jià)格就明白了)。像L0 寄存器,每個(gè)寄存器只能存儲(chǔ)一個(gè)字長(zhǎng)的內(nèi)容,但是CPU讀寫取寄存器耗費(fèi)的時(shí)鐘周期為0個(gè)。這是最快的速度。

另外,我們?cè)陔娔X主板上可以看到內(nèi)存條(L4主存)。硬盤(L5),但是卻沒看到L3-L0。原因很簡(jiǎn)單,他們都是集成在CPU芯片內(nèi)部的。

我們知道了存儲(chǔ)器的層級(jí)結(jié)構(gòu),下面還有一個(gè)問題,就是怎么把硬盤,內(nèi)存條之類的連接起來進(jìn)行通信呢,這就是 總線(Bus)了。

 

上圖存在三條總線,IO總線,存儲(chǔ)器總線(通常稱為內(nèi)存總線),系統(tǒng)總線。在主板上,就是那一排排的32/64根并行的導(dǎo)線。這些導(dǎo)線用來連接CPU,內(nèi)存,硬盤,以其他外圍設(shè)備。CPU與存儲(chǔ)器,輸入輸出設(shè)備等通信,都是通過總線。不同總線的速度也有差異。

CPU要通過I/O橋(就是主板的北橋/南橋芯片組)與外圍設(shè)備連接,因?yàn)镃PU的主頻太高了,它的時(shí)鐘周期一秒鐘震蕩幾億次,外圍設(shè)備的時(shí)鐘周期都較慢,所以他們不能直接通信。

本文是討論軟件的,所以硬件部分就一筆帶過,讀者知道有這回事就ok了。總線上攜帶地址,數(shù)據(jù)和控制信號(hào), 如何區(qū)分不同信號(hào),分辨它與哪個(gè)外圍設(shè)備通信,這就是另外一個(gè)問題了。

不管中間怎么加緩存,數(shù)據(jù)從硬盤到內(nèi)存的速度就是那么慢,那么這些緩存意義何在?

有些讀者腦子轉(zhuǎn)的比較快,可能想到了這樣一個(gè)問題。

不管你中間怎么加緩存,也不管中間的什么SRAM,DRAM的讀寫速度有多快,但是磁盤的讀寫速度就是那么慢,所以磁盤與主存之間的交互速度很慢。CPU歸根到底需要向磁盤讀寫數(shù)據(jù)。整個(gè)環(huán)節(jié)速度瓶頸就是在磁盤那里,這個(gè)根本快不了,那么加那么多級(jí)緩存,意義有何在呢?

這是一個(gè)好問題啊。 下面讓我們繼續(xù)討論。

我們來看看,CPU如何讀取磁盤中的一個(gè)數(shù)據(jù)。

 

網(wǎng)上找的圖片不是很清楚,注意每張圖中的黑線。步驟分三部:

  • CPU 將相關(guān)的命令和地址,通過系統(tǒng)總線和IO總線傳遞給磁盤,發(fā)起一個(gè)磁盤讀。
  • 磁盤控制器將相關(guān)的地址解析,并通過IO總線與內(nèi)存總線將數(shù)據(jù)傳給內(nèi)存。
  • 第2步完成之后,磁盤控制器向CPU發(fā)送一個(gè)中斷信號(hào)。(學(xué)電子的同學(xué)應(yīng)該很清楚中斷是什么)。這時(shí)CPU就知道了,數(shù)據(jù)已經(jīng)發(fā)送到內(nèi)存了。

第二步磁盤操作很慢,但是在第一步CPU發(fā)出信號(hào)后。但是第二步和第三部時(shí),CPU根本不參與。第二步很耗時(shí),所以CPU在第一步發(fā)出信號(hào)后,就去在干其他事情啊。(切換到另一個(gè)線程)。所以此時(shí)的CPU依舊沒有閑著。而待第三步時(shí),通過中斷,硬盤主動(dòng)發(fā)信號(hào)給CPU,你需要的數(shù)據(jù)已經(jīng)發(fā)送到內(nèi)存了,然后此時(shí)它可以將線程再切換回來,接著執(zhí)行這個(gè)該線程的任務(wù)。

除了多線程切換,避免CPU閑置浪費(fèi),還有一點(diǎn)。

我先問一個(gè)問題。

  1. //@author :www.yaoxiaowen.com 
  2. int main(){ 
  3.  //我們執(zhí)行任務(wù)的代碼 
  4.  return 0; 

對(duì)于一個(gè)應(yīng)用/進(jìn)程而言,它都應(yīng)該有一個(gè)入口。(雖然不一定需要我們直接寫main函數(shù))。入口函數(shù)內(nèi)部就是我們的任務(wù)代碼,任務(wù)代碼執(zhí)行完了這個(gè)應(yīng)用/進(jìn)程也就結(jié)束了。這個(gè)很好理解,比如測(cè)試工程師寫的一個(gè)測(cè)試case。跑完了這個(gè)任務(wù)就結(jié)束了。

但是 有些程序,比如一個(gè) app,你打開了這個(gè)app。不做任何操作。這個(gè)界面會(huì)一直存在,也不會(huì)消失。思考一下這是為什么。因?yàn)檫@個(gè)app進(jìn)程肯定也要有一個(gè)main入口。 main里面的任務(wù)代碼執(zhí)行完了,就應(yīng)該結(jié)束了。而一個(gè)程序的代碼/指令數(shù)目肯定是有限的。但該app在我們不主動(dòng)退出情況下,卻不會(huì)主動(dòng)結(jié)束。

所以這個(gè)app進(jìn)程的入口main來講,其實(shí)是這樣的。

 

并且不僅如此,在一個(gè)程序內(nèi)部,也有大量的for,while等循環(huán)語句。

那么當(dāng)我們把這些相關(guān)的代碼指令送到了主存,或者更高一級(jí)的緩存時(shí),那么CPU在執(zhí)行這些指令時(shí),存取速度自然快了很多。

在執(zhí)行一個(gè)程序時(shí),啟動(dòng)階段比較慢,因?yàn)樾枰獜拇疟P讀取數(shù)據(jù)。(而CPU在這個(gè)階段也沒閑置浪費(fèi),它會(huì)進(jìn)行線程切換執(zhí)行其他任務(wù))。 但是數(shù)據(jù)被送往內(nèi)存之后,它執(zhí)行起來就會(huì)快多了,并且伴隨著執(zhí)行過程,還可能越來越快,因?yàn)檫@些數(shù)據(jù),有可能被一級(jí)一級(jí)的向上送,從L4,送到L3,再送到L2,L1

so,上述那個(gè)問題的答案,已經(jīng)解釋的比較清楚了吧。

局部性原理(Principle of locality)

locality對(duì)于硬件和軟件系統(tǒng)的設(shè)計(jì)和性能都有著重要的影響。對(duì)于我們理解存儲(chǔ)器的層次結(jié)構(gòu)也必不可缺。

程序傾向于引用臨近于與其他最近引用過的數(shù)據(jù)項(xiàng)的數(shù)據(jù)項(xiàng)。或者最近引用過的數(shù)據(jù)項(xiàng)本身。這種傾向性,我們稱之為局部性原理。它通常有以下兩種形式:

  • 時(shí)間局部性(temporal locality):被引用過一次的存儲(chǔ)器位置的內(nèi)容在未來會(huì)被多次引用。
  • 空間局部性(spatial locality):如果一個(gè)存儲(chǔ)器位置的內(nèi)容被引用,那么它附近的位置也很大概率會(huì)被引用。

一般而言,有良好局部性的程序比局部性差的程序運(yùn)行的更快。 現(xiàn)代計(jì)算機(jī)系統(tǒng)的各個(gè)層次,從硬件到操作系統(tǒng)、再到應(yīng)用程序,它們的設(shè)計(jì)都利用了局部性。

當(dāng)然,光說理論的東西比較玄乎。我們來看實(shí)際的例子。

 

在這個(gè)程序中,變量sum,i在每次循環(huán)迭代時(shí)被引用一次,因此對(duì)sum和i來說,有較好的時(shí)間局部性。

對(duì)變量array來說,它是一個(gè)int類型數(shù)組,循環(huán)時(shí)按順序訪問array,因?yàn)橐粋€(gè)C數(shù)組在內(nèi)存中是占用連續(xù)的內(nèi)存空間。因而的較好的空間局部性,

再來看一個(gè)例子:

 

這是一個(gè)空間局部性很差的程序。

假設(shè)這個(gè)數(shù)組是array[3][4],因?yàn)镃數(shù)組在內(nèi)存中是按行順序來存放的。所以sum2對(duì)每個(gè)數(shù)組元素的訪問順序成了這樣:0, 4, 8, 1, 5, 9…… 7, 11。所以它的空間局部性很差。

但是幸運(yùn)的是,一般情況下軟件編程天然就是符合局部性原理的。比如程序的循環(huán)結(jié)構(gòu)。

假設(shè)CPU需要讀取一個(gè)值,int var,而var在L4主存上,那么該值會(huì)被依次向上送,L4->L3->L2,但是這個(gè)傳遞的過程并不是單純的只傳遞var四個(gè)字節(jié)的內(nèi)容,而是把var所在的內(nèi)存塊(block),依次向上傳遞,為什么要傳遞block?因?yàn)楦鶕?jù)局部性原理,我們認(rèn)為,與var值相鄰的值,未來也會(huì)被引用。

存儲(chǔ)器的層次結(jié)構(gòu),數(shù)據(jù)進(jìn)行傳送時(shí),是以block(塊)為單位傳送的。在整個(gè)層次結(jié)構(gòu)上,越往上,block越小而已。

存儲(chǔ)器層次結(jié)構(gòu)中的緩存

洋洋灑灑的扯了那么多,我相對(duì)于所謂的 存儲(chǔ)器層次結(jié)構(gòu)讀者應(yīng)該有一個(gè)基本的認(rèn)識(shí),有些地方介紹的 不夠嚴(yán)謹(jǐn),但是本文的目的也就是讓大家理解基本思想。

歸根到底,它就是一個(gè)緩存(caching)的思想,并且其實(shí)不復(fù)雜,

我們做app開發(fā)時(shí),對(duì)于app中活動(dòng)頁(yè)面等,都是后臺(tái)發(fā)給我們圖片url,我們下載后才顯示在app上,這時(shí)我們總要使用 Glide,Picasso 等圖片緩存框架來把下載好的圖片緩存在手機(jī)本地存儲(chǔ)上。這樣下次打開app時(shí),如果這個(gè)圖片鏈接沒有改變,我們就直接拿手機(jī)本地緩存的圖片來進(jìn)行顯示,而不用再?gòu)姆?wù)器上下載了。如果圖片鏈接改變了,則重新下載。為什么要這么做?因?yàn)閺姆?wù)器上下載比較慢,而手機(jī)本地存儲(chǔ)(ROM)中讀取就會(huì)快很多。

這個(gè)時(shí)候可以再回頭看看"圖4:一個(gè)存儲(chǔ)器層次結(jié)構(gòu)的示例"。

下面這張圖和這段文字來自《深入理解計(jì)算機(jī)系統(tǒng)》(CSAPP),大家可以有個(gè)更嚴(yán)謹(jǐn)和細(xì)節(jié)的認(rèn)識(shí)。

 

存儲(chǔ)器層次結(jié)構(gòu)的中心思想:位于k層的更快更小的存儲(chǔ)設(shè)備作為位于k+1層得更大更慢的存儲(chǔ)設(shè)備的緩存;數(shù)據(jù)總是以塊大小為傳送單元(transfer unit)在第k層和第k+1層之間來回拷貝的;任何一對(duì)相鄰的層次之間傳送的塊大小是固定的,即每一級(jí)緩存的塊大小是固定的。但是其它的層次對(duì)之間可以有不同的塊大小。

當(dāng)程序需要第k+1層的某個(gè)數(shù)據(jù)對(duì)象d時(shí),它首先在當(dāng)前存儲(chǔ)在第k層的一個(gè)塊中查找d。如果d剛好在k層,那么就是緩存命中。如果第k層中沒有緩存數(shù)據(jù)對(duì)象d,那么就是緩存命不中。當(dāng)緩存不命中發(fā)生時(shí),第k層的緩存從第k+1層 緩存中取出包含d的那個(gè)塊,如果第k層的緩存已經(jīng)滿了的話,可能會(huì)覆蓋現(xiàn)存的一個(gè)塊。(覆蓋策略可以使用常見的LRU算法)。

volatile 關(guān)鍵字

在java和C當(dāng)中,有一個(gè)volatile關(guān)鍵字(其他語言估計(jì)也有),它的作用就是在多線程時(shí)保證變量的內(nèi)存可見性,但是具體怎么理解呢?

我們?cè)?quot;圖4:一個(gè)存儲(chǔ)器層次結(jié)構(gòu)的示例"中,說的緩存結(jié)構(gòu)其實(shí)對(duì)于一個(gè)單核CPU而言的,比如 對(duì)于 一個(gè)四核三級(jí)緩存的CPU,它的緩存結(jié)構(gòu)是這樣的。

 

 

我們可以看到L3是四個(gè)核共有的,但是L2,L1其實(shí)是每個(gè)核私有的,如果我有一個(gè)變量var,它會(huì)被兩個(gè)線程同時(shí)讀取,這兩個(gè)線程在兩個(gè)核上并行執(zhí)行,因?yàn)槲覀兊木彺嬖?,這個(gè)var可能分別在兩個(gè)核的 L2或L1緩存,這樣讀取速度最快,但是該var值可能就分別被這兩個(gè)核分別修改成不同的值, 最后將值回寫到L3或L4主存,此時(shí)就會(huì)發(fā)生bug了。

所以volatile關(guān)鍵字就是預(yù)防這種情況,對(duì)于被volatile修飾的的變量,每次CPU需要讀取時(shí),都至少要從L3讀取,并且CPU計(jì)算結(jié)束后,也立刻回寫到L3中,這樣讀寫速度雖然減慢了一些,但是避免了該值在每個(gè)core的私有緩存中單獨(dú)操作而其他核不知道。

責(zé)任編輯:武曉燕 來源: 悅碼
相關(guān)推薦

2021-04-22 08:39:23

哈佛結(jié)構(gòu)馮洛伊曼結(jié)構(gòu)ARM架構(gòu)

2018-03-21 09:24:27

超融合架構(gòu)層次存儲(chǔ)

2010-04-05 17:04:22

約翰·馮·諾依曼生平

2017-11-03 11:15:15

IBM

2020-07-20 09:18:43

存儲(chǔ)數(shù)據(jù)技術(shù)

2021-04-29 14:48:09

云存儲(chǔ)架構(gòu)云計(jì)算

2023-10-08 07:19:41

flynn分類法存儲(chǔ)器

2018-05-10 09:51:39

Spark內(nèi)存Hadoop

2019-05-29 09:33:35

存儲(chǔ)技術(shù)容器

2018-10-22 12:18:50

存儲(chǔ)器內(nèi)存寄存器

2022-03-01 17:26:35

華為數(shù)字化

2019-12-18 14:14:40

程序員存儲(chǔ)程序

2013-12-25 09:39:36

程序員代碼

2010-07-09 09:37:00

HART協(xié)議

2010-04-21 16:07:04

Oracle邏輯存儲(chǔ)結(jié)

2012-07-09 09:38:38

2010-04-21 16:55:06

Oracle物理存儲(chǔ)結(jié)

2021-12-03 13:52:25

AI 數(shù)據(jù)人工智能

2023-08-09 09:30:10

數(shù)組結(jié)構(gòu)left )

2022-10-31 14:02:24

匯編語言神經(jīng)網(wǎng)絡(luò)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)