作者:老劉
上帝為你關(guān)閉了一扇門,就一定會(huì)為你打開一扇窗我是CPU, 他們都叫我阿甘, 因?yàn)槲液汀栋⒏收齻鳌防锏陌⒏室粯樱? 有點(diǎn)傻里傻氣的。上帝把我制造出來, 給我了一個(gè)很小的腦容量, 為數(shù)不多的寄存器能臨時(shí)的記一點(diǎn)東西, 但是上帝給我打開了一扇特別的窗戶, 那就是像阿甘一樣,跑的飛快。到底有多快呢? 我這么比喻一下吧, 我的工作都是以納秒為單位的, 你們?nèi)碎g的一秒, 我可能已經(jīng)做了1000,000,000 (10億)次動(dòng)作了。相比而言, 內(nèi)存比我慢100倍, 硬盤比我慢1000多萬倍, 你說我快不快?我住在一個(gè)機(jī)箱里,每天早上一陣電流把我叫醒, 還夾雜著嗡嗡的聲音, 我知道我忠實(shí)的護(hù)衛(wèi)電風(fēng)扇又開始工作了, 我特別怕熱, 又運(yùn)行的飛快, 如果沒有電風(fēng)扇給我降溫, 我很快就會(huì)生病, 生病的后果很嚴(yán)重, 那就是我的伙伴們像內(nèi)存了,硬盤了。。全部都要罷工了, 沒有我這個(gè)系統(tǒng)就會(huì)陷入的一片死寂。我聽說有些CPU的福利很好,竟然待在恒溫恒濕,一塵不染的托管機(jī)房里,讓我好生羨慕。我的腦容量很小, 所以醒來后只想起了我的創(chuàng)造者告訴我的幾件事情 :2. 你不能保存指令, 你的指令全在內(nèi)存里3. 你的第一條指令在內(nèi)存的最頂端處0xFFFFFFF0那還有什么可說的, 趕緊打電話給內(nèi)存要指令,電話通過系統(tǒng)總線, 還得通過I/O橋電話局需要轉(zhuǎn)接一下, 再通過存儲(chǔ)總線接通 內(nèi)存。 '哥們, 把這個(gè)地址處的指令給我說一下吧''你是誰?' 內(nèi)存竟然把我忘了, 當(dāng)然,他斷了電和我一樣,失憶了。'我是阿甘啊, 我們經(jīng)常聊天來著, 你忘了?'內(nèi)存磨磨唧唧半天才把數(shù)據(jù)發(fā)了過來(比我慢100倍?。?這是一條跳轉(zhuǎn)指令, 我立刻回憶起來了, 這是我的老朋友BIOS 等著我去運(yùn)行他那一堆指令呢。我給BIOS打電話: “老弟,今天干點(diǎn)啥?”“阿甘,早上好 ' BIOS從不失憶,把所有人都記得清清楚楚 “ 還不是老一套啊,無非做一下系統(tǒng)的自檢, 看看內(nèi)存,硬盤,顯卡等這些老伙計(jì)們有沒有問題, 有問題的話用小喇叭提示一下主人 ”這些過程我已經(jīng)輕車熟路了, 很快搞定, 像往常一樣,沒有問題, 我還把一個(gè)叫做中斷向量表的東西給弄好了, 我知道一會(huì)而要用這些東西都搞完了,BIOS果然告訴: '阿甘, int 0x19'我趕緊去剛弄好的中斷向量表中去查第19號(hào), 順藤摸瓜又找到對(duì)應(yīng)0x19的一大堆指令。執(zhí)行吧, 這堆指令把將磁盤的第一扇區(qū)(磁盤最開始的512字節(jié))運(yùn)到內(nèi)存的0X0000:0X7C00處,然后我就從此處接著執(zhí)行。我想起來了, 接下來有一大堆精巧的指令把迷迷糊糊的操作系統(tǒng)從硬盤中喚醒, 運(yùn)輸?shù)絻?nèi)存中來。(此處實(shí)在是復(fù)雜, 略去10萬字。。。。)你看這就是為啥他們叫我阿甘, 我做事飛快,但非得別人告訴去哪里執(zhí)行才行, 要不然我就只會(huì)坐在那里無所適從。操作系統(tǒng)一旦進(jìn)入內(nèi)存,立刻就是老大, 所有人都得聽他指揮。我也發(fā)現(xiàn)我的周圍出現(xiàn)了一個(gè)屋子:進(jìn)程屋屋里堆著一大堆東西, 什么進(jìn)程描述信息包裹了, 進(jìn)程控制信息包裹了, 我都不太關(guān)心, 我只關(guān)心最最重要的兩件東西:1. 我工作必備的寄存器, 就放在我面前的工作臺(tái)上。2. 程序計(jì)數(shù)器, 我用它記住我要執(zhí)行的下一條指令地址。'阿甘, 別來無恙啊' , 操作系統(tǒng)對(duì)我還是挺不錯(cuò)的, 先給我打招呼。'Linux老大, 今天有什么活啊', 我每次都表現(xiàn)的積極主動(dòng)。'來,把這個(gè)hello world 程序給運(yùn)行了'Hello world 程序還在硬盤上睡著呢, 得先把他也裝載到內(nèi)存里, 要不然我怎么執(zhí)行啊。于是我就拿起電話打給硬盤, 電話通過系統(tǒng)總線來到IO橋電話局, 再轉(zhuǎn)接到IO總線,這才來到硬盤這里。 我在電話里請(qǐng)他把數(shù)據(jù)給我運(yùn)過來, 然后我就無所事事的坐在那里等。Linux 老大立刻就怒了 : 阿甘, 告訴你多少次了, 你小子怎么還在等硬盤給你發(fā)數(shù)據(jù)!是的, 我忘了一件事,硬盤比我慢太多了, 我執(zhí)行一條指令大概是1ns ,在用來讀磁盤的16ms里, 我能潛在的執(zhí)行1600多萬條指令啊。我感到深深的愧疚, 趕緊拿起電話打給硬盤 : 哥們, 按我們之前商量好的,用直接內(nèi)存訪問(DMA)啊, 你直接把數(shù)據(jù)裝載到內(nèi)存吧, 不用經(jīng)過我了, 裝載完成以后給我發(fā)個(gè)信號(hào)。“阿甘,數(shù)據(jù)還沒來, 別閑著, 這有一個(gè)菲波那切數(shù)列數(shù)列, 來算一下吧”'肥波納妾數(shù)列? 這名字好古怪,老大, 其實(shí)你也知道, 我腦子小,懶得去理解那是啥意思, 你把進(jìn)程屋切換下,把程序計(jì)數(shù)器設(shè)置好,指向下一條指令, 我一條條指令執(zhí)行就得了“ 我挺沒追求的。我所處的進(jìn)程屋立刻發(fā)生了變化(當(dāng)然,這也是我輔助Linux老大干的), 各種包裹的信息都變了, 尤其是寄存器和程序計(jì)數(shù)器。于是我就開始計(jì)算這個(gè)什么納妾數(shù)列 ,但是這個(gè)數(shù)列似乎無窮無盡, 哪個(gè)無腦子的程序員寫了個(gè)無限循環(huán)吧。正在這時(shí), 我便收到了一個(gè)電話, 說是Helloworld的數(shù)據(jù)已經(jīng)裝載到內(nèi)存了, 讓我去處理。我放下手中的活, 保存好現(xiàn)場(chǎng), 就去處理那個(gè)Helloworld, 果然數(shù)據(jù)已經(jīng)都好了, 那就切換過去運(yùn)行吧。其實(shí)老大并不知道, 任何人,只要你運(yùn)行了相當(dāng)多的數(shù)量的指令以后, 你都能悟到這些程序的秘密。 我CPU阿甘雖然傻傻的, 但也架不住執(zhí)行這數(shù)以萬萬億的指令給我的熏陶啊。這個(gè)秘密就是:程序都是由順序,分支,循環(huán)來組成的。 其實(shí)分支和循環(huán)在我看來都是跳轉(zhuǎn)而已。所以我的工作就是打電話問內(nèi)存要一條指令, 執(zhí)行這個(gè)指令, 如果是個(gè)跳轉(zhuǎn)指令的話,我就問內(nèi)存要跳轉(zhuǎn)的目標(biāo)地址的那一條指令, 繼續(xù)執(zhí)行, 生活就是這么簡(jiǎn)單。奧對(duì)了, 當(dāng)然也有復(fù)雜的, 就是函數(shù)調(diào)用, 我得和內(nèi)存緊密配合才能完成。 這個(gè)咱下回再說。提到內(nèi)存, 這真是我的好哥們, 沒有他,我?guī)缀跏裁词聝憾几刹怀桑?更重要的是他比硬盤快的多, 讀取一次數(shù)據(jù), 只需要 100 納秒左右。 這樣我們倆說起話來就輕松多了。每次他都說: '阿甘, 幸虧有你給我聊天, 要不然我肯定被活活的悶死不可, 那個(gè)硬盤說話是在太慢了''硬盤是個(gè)機(jī)械是的玩意, 一個(gè)磁頭在一碟高速旋轉(zhuǎn)的磁片上挪來挪去,光定位就慢死了''人家雖然慢, 但是不怕停電, 哪像你和我,一停電全部都失去記憶了。'我的指令中有些完全用我的寄存器就能完成, 但是有很多都需要讀寫內(nèi)存的數(shù)據(jù), 再加上所有的指令都在內(nèi)存中存著, 雖然它只比我慢個(gè)100倍, 但指令多了我還是有點(diǎn)受不了。我給內(nèi)存說:'哥們, 你能不能再快點(diǎn)!'內(nèi)存說: 拜托, 這已經(jīng)是我的極限了, 阿甘, 你自己再想想辦法吧 ! 我給你說啊, 我留意了你最近訪問的指令和數(shù)據(jù), 我發(fā)現(xiàn)了個(gè)規(guī)律“'比如說吧, 你訪問了我一個(gè)內(nèi)存位置以后過不多久還會(huì)多次訪問, 還有,一個(gè)內(nèi)存位置被訪問了, 附近的位置很快也會(huì)訪問到'(碼農(nóng)翻身注: 這其實(shí)叫程序的局部性原理)我還以為是啥規(guī)律, 其實(shí)我早就注意到了。'既然你經(jīng)常訪問同一塊區(qū)域的東西, 你想想如果把這些東西緩存在你那里會(huì)怎么樣.... '從此以后,我每次讀寫指令和數(shù)據(jù), 都問緩存要, 緩存沒有才給內(nèi)存打電話。果然, 由于局部性原理的存在, 我發(fā)現(xiàn)的確是快了不少啊。當(dāng)然也有缺點(diǎn), 那就是Linux老大在做程序切換的時(shí)候, 緩存就會(huì)失效,因?yàn)閮蓚€(gè)程序之間沒什么聯(lián)系,局部性原理不起作用, 所以需要重建緩存。緩存讓我的工作更有效率, 得到了Linux老大的表揚(yáng):'阿甘, 我看你很聰明嘛, 都會(huì)用緩存了''我哪有那么聰明,都是內(nèi)存的點(diǎn)子。老大,不過我學(xué)會(huì)了一個(gè)重要的東西 :當(dāng)你改變不了別人的話,抱怨也沒用, 還是先改變一下自己吧''挺有哲理的嗎, 希望你明天重啟后還能想起來' Linux老大笑話我。'我最近又發(fā)現(xiàn)了一個(gè)問題, 正苦惱著呢, 你看我有四只手, 第一只手負(fù)責(zé)打電話問內(nèi)存要指令, 第二只手翻譯指令, 第三只手真正執(zhí)行, 第四只手有時(shí)候還得把結(jié)果寫回內(nèi)存。 問題是, 我發(fā)現(xiàn)經(jīng)常只有一只手在忙活, 其他都在閑著, 你看第一只手取指令, 其他手只能等著。 第二只手翻譯指令的時(shí)候,其他三只也得等“'看來以后我們不能叫你阿甘了, 你已經(jīng)開始思考了' Linux老大笑了 “這問題好解決, 給你舉個(gè)例子,你聽說過洗車沒有? 和你差不多, 也是先噴水, 再打洗潔劑, 再擦洗, 最后烘干, 但人家的工作方式和你不一樣,人家是流水線作業(yè), 你想想, 一輛車在烘干的時(shí)候, 后邊是不是還有三輛車,分別在噴水, 打清潔劑 和擦洗 , 每個(gè)步驟都不會(huì)空閑。 ”'這么簡(jiǎn)單的道理我怎么都沒有想到呢? 我也可以搞個(gè)流水線啊, 這樣每只手都利用起來了'別人都說我們高科技, 但其實(shí)原理都蘊(yùn)含在生活之中啊。 有了緩存和流水線的幫助, 讓我的工作大大的加快了,大家都對(duì)我刮目相看?!∷麄兿虢o我起個(gè)新名字:超人 , 不過我還是更喜歡 他們叫我“阿甘”, 多親切。
|