還記得我嗎,我是阿Q,CPU一號車間的那個阿Q。編程
今天忙裏偷閒,來到廠裏地址翻譯部門
轉轉,負責這項工做的小黑正忙得滿頭大汗。瀏覽器
看到個人到來,小黑指着旁邊的座椅示意讓我坐下。編程語言
坐了好一下子,小黑才從工位上忙完轉過身來,「實在很差意思阿Q,今天活太多,沒來得及招待你」源碼分析
「剛忙什麼呢,看你滿頭大汗的」,我問道。性能
「嗨,別提了,總是發現內存頁面錯誤,不停地要通知操做系統那邊去處理,真是懷念之前啊,沒有這麼多破事兒要管」,小黑嘆了口氣。操作系統
我一聽來了興趣,「小黑你給我說說大家的工做唄,地址翻譯是怎麼一回事兒,爲何懷念之前呢?」線程
小黑調整了下坐姿,咕嚕咕嚕喝了幾口水說道,「這話說來可就話長了」翻譯
接下來小黑開始給我講起了歷史故事······3d
原來我們的祖先叫8086,小黑還給我看了他的照片code
那是一個純真質樸的年代,雖然工做性能不高,不過那個年代的程序都很簡單,咱們的祖先一問世就成爲了明星,稱得上那個時代的頂流了。
看到照片中的那些金屬針腳了嗎?那是咱們CPU和外界打交道的觸角,每一根都有不一樣的做用。
經過這些觸角,CPU就能夠跟內存打交道,獲取指令和數據,辛勤的幹活啦。
那個年代,條件比較差,能湊合的就湊合,能共用的就共用。這不,你看祖先CPU的地址總線針腳和數據總線針腳就共用了。
祖先是一個16位的CPU,數據(Data)總線就有16位,一次性能夠傳輸16個比特位。和地址(Address)總線湊合着一塊兒共用,因而就取名AD0-AD15。
不過祖先的地址總線卻不止16個,還多出了A16-A19整整4個呢!這樣有20個地址線,能夠尋址1MB的內存了!
可是祖先的寄存器都是16位的啊,只能存放16位的地址。不過他們很聰明,發明了一個叫分段式存儲管理
的方法,把內存劃分爲最大64KB的小塊,爲何是64KB呢,由於16位地址最多隻能尋址這麼大了。而後又加了幾個叫作段寄存器的東西,指向這些塊的開頭,這樣,經過段地址+段內偏移地址的方式,就能訪問更多的內存了。
後來啊,祖先的那點計算能力愈來愈捉襟見肘,實在是跟不上時代了。家族中的年輕一代開始挑大樑,80286和80386CPU相繼問世,尤爲是80386,成爲了劃時代的存在。
到了80386時代,咱們與外界通訊的引腳就更多了,而且變成了32位的CPU,那個時候,生活條件就變好了,地址線和數據線不再用共享引腳了。
後來,人類變得愈來愈貪心,想要一邊聽音樂,一邊還要上網,同時還要編輯文檔,這就同時須要運行多個程序。
這個時候,有人發現了商機,開發了一個叫操做系統
的東西,原來那些程序再也不直接和咱們CPU打交道了,而是和操做系統打交道,操做系統再和咱們打交道,中間商賺差價說的就是他們!
操做系統這玩意兒很聰明啊,經過時間片劃分讓咱們CPU來輪流執行多個程序,一下子讓咱們執行音樂播放,一下子讓咱們執行瀏覽器程序,一下子又讓咱們執行文檔編輯程序。咱們是無所謂啊,給什麼代碼不是代碼啊,咱們不挑,埋頭苦幹就是了。人類的反應速度跟咱們就差得遠了,他們還覺得這些程序真的是同時執行的呢。
不過隨之而來出現了一個大問題,這麼多程序都要運行,你們擠在一個內存裏,常常發生摩擦,衝突不斷。
先祖們爲了此事殫精竭慮,終於想出了一個好辦法,一直沿用至今。
他們提出了一個虛擬地址
的東西,全部程序使用的地址都是一個虛擬的地址,在真正和內存打交道的時候,我們CPU內部工做人員再給翻譯成真實的內存地址,關於這事兒,內存那傢伙一直被咱們矇在鼓裏。
這樣一來,每一個程序均可以用的是0x00000000到0xffffffff總共4GB這麼大範圍的地址空間,固然不會真的給他們那麼多空間,內存那傢伙總共才4GB呢,而是要按需申請分配。分配的單元是按照頁
來進行的,32位的CPU一個頁是4KB。這些分配管理的累活就讓操做系統來幹了,中間商不能光拿好處不幹正事,至於咱們CPU,作好地址翻譯的工做就行了。
爲此,在咱們寄存器內部專門添置了一個新的寄存器CR3,用來指向一個地址翻譯查詢字典,字典劃分了兩級目錄。咱們把一個32位的地址劃分了3部分,前面兩部分分別指向兩級目錄中的條目,用來定位這個地址在物理內存的哪一個頁面,最後一部分就是指向物理內存頁面的偏移,這樣就完成了地址的翻譯工做。
每一個進程有不一樣的地址空間,切換進程的時候,把CR3的內容換一下就使用新進程的翻譯字典,特別的方便。
咱們把這種內存管理方式叫作分頁式內存管理
。
真佩服先祖們的智慧,這樣巧妙的把各個程序隔離開來,後來咱們把這種工做模式叫作保護模式
,把以前那種直接使用真實內存地址的工做模式叫作實地址模式
。
人類變得愈來愈貪婪,程序變得愈來愈多,對內存的需求也愈來愈大。隨着這些程序都不斷申請內存頁面,內存空間很快就要耗盡了。
咱們看在眼裏,急在內心,後來找操做系統協商,看看這問題該怎麼辦。
操做系統那傢伙也不賴,想出了一個好辦法。內存的大小有限,可是硬盤給力啊,硬盤空間大的多,去硬盤上劃一塊區域來,把內存里長時間沒有用到的頁面給換到這塊區域裏去,而後作個標記。若是後面誰要訪問那個頁面,我們CPU就檢查若是有這個標記,就發送一個頁錯誤的中斷信號告訴操做系統去把這個頁面換回來。
經過咱們之間的配合,解決了內存緊張的危機。後來咱們把這個技術叫作內存分頁交換
。
時間過得很快,到了咱們這一輩,內存變得更大了,16GB都是小case,32GB也很常見。
除了內存,咱們CPU自己也更先進了,別的不說,你光看看我們如今的引腳數那比先祖們那幾輩就不可同日而語。
咱們不只從32位變成了64位,還從單核變成了多核,像我所在的CPU就有8個車間,8核並行執行,比起先祖那個年代簡直有云泥之別。
和小黑閒談間,咱們車間的老K忽然出如今了門口。
「阿Q原來你在這裏,讓我好找,趕快回去吧,隔壁二號車間的虎子說咱們改了他們的數據,上門來鬧事了······」
預知後事如何,請關注後續精彩······