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