日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

一步步编写操作系统 30 cpu的分支预测简介

發布時間:2023/12/10 windows 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一步步编写操作系统 30 cpu的分支预测简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

人在道路的分岔口時要預測哪條路能夠到達目的地,面對眾多選擇時,計算機也一樣要抉擇,畢竟計算機的運行方式是以人的思路來設計的,計算機中的抉擇其實就是人在抉擇。

cpu中的指令是在流水線上執行。分支預測,是指當處理器遇到一個分支指令時,是該把分支左邊的指令放到流水線上還是把分支右邊的指令放在流水線上呢?

如C語言程序中的if、switch、for等語言結構,編譯器將它們編譯成匯編代碼后,在匯編一級來說,這些結構都是用跳轉指令來實現的,所以,匯編語言中的無條件跳轉指令很豐富,以至于稱之為跳轉指令“族”,多的足矣應對各種轉移方式。

舉個例子,如下面測試代碼

1 void main () { 2 int i = 0; 3 while (i < 10) { 4 i++; 5 } 6 }

里面的while結構,就是執行了10次i++。我們來看一下while結構是如何翻譯成匯編語言的。

gcc -S -o ~/test/while.S ~/test/while.c回車,這樣gcc就將while.c編譯成了匯編代碼while.S。其中的參數-S是編譯到匯編語言,不進行匯編和鏈接。

查看下~/test /while.S文件,cat -n ~/test/while.S回車

1 .file "while.c"2 .text3 .globl main4 .type main, @function5 main:6 pushl %ebp7 movl %esp, %ebp8 subl $16, %esp9 movl $0, -4(%ebp) 10 jmp .L2 11 .L3: ;此處是while的循環體 12 addl $1, -4(%ebp) 13 .L2: ;此處是while循環條件表達式 14 cmpl $9, -4(%ebp) 15 jle .L3 16 leave 17 ret 18 .size main, .-main 19 .ident "GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4)" 20 .section .note.GNU-stack,"",@progbits

這個生成的匯編語言并不是我們熟悉的intel語法,而是AT&T語法,如果此時您覺得太陌生也不要慌張,因為在后面的章節我們會專門說到此類語法,現在先拋出來和大家預預熱。

本來打算只列出第9~15行的,但考慮到本身才20行,干脆就全貼出來了,簡要說明下,前4行是用于聲明代碼段、導出main函數符號。第5行是main函數起始地址,高級語言中的函數名在匯編語言中只是個符號,而符號便是地址,這就是很多教科書上都說函數名是地址的原因。話說數組也同理,數組名在匯編語言中也是個標號地址,所以數組名也是地址。局部變量是在棧中分配空間的,所以第6~8行是在創建堆棧框架,也就是為局部變量i在棧中分配空間,-4(%ebp)便是指局部變量i。堆棧框架以后會說到。咱們主要是看第9~15行。

第9行是為變量i賦值為0。AT&T語法中,寄存器前要用%來指示,立即數前要用$來指示。-4(%ebp)表示內存地址“ebp寄存器的值減4”處內存內容。相當于intel匯編語法形式[ebp – 4]。AT&T語法中是源操作數在左,目的操作數在右,和intel語法相反。所以第9行是將0送入了變量i所在的棧空間。

第10行就是簡單的無條件跳轉,直接進入while循環結構的條件表達式判斷,也就是第13行。

第14行就是while括號中的條件表達式,用變量i的值和立即數9做比較。

第15行的jle意思是,若第14行的比較結果是小于等于9,則跳到11行,繼續執行第12行的加法。可見第11~12行則是循環體。

程序執行流是由第15行跳到第11行,這樣組成了循環結構的回路。

程序執行while循環后就結束了,所以局部變量i所在的棧空間要被回收,第16行的指令leave是用于堆棧框架的回收工作。

第17行是main函數退出。由于main也是被調用的,所以gcc顯示的幫咱們加了個ret以示退出,為什么main也是由別人調用的,這個在加載用戶程序時咱們會說到的。

上面的第15行jle指令就是程序中的分支結構。我們花了“大力氣”講述了程序流的分支,這并不是浪費力氣。類似這樣的分支結構很多,它們只有兩種結果,要么轉移到這一邊,要么轉移到那一邊。分支結構雖然讓程序更加靈活多樣,但這卻成了cpu執行效率的詬病。這是怎么回事呢?

之前說流水線的時候,我和大家強調了兩次“重疊”,即同一時間周期內完成的是當前指令的執行,下一條指令的譯碼,第三條指令的取指。其中最重要的是“執行”,指令只有執行了,才真正是潑出去的水,收不回來了。另外的譯碼和取指并不重要,首先它們并不是執行,其次它們也不屬于當前指令,當前指令的“取指”和“譯碼”早就在前兩個周期內完成了。

不知道您注意到了沒有,拿表4-14的周期3來說,這一時鐘周期內的“執行”是指的當前指令的執行階段,“取指”和“譯碼”這兩個工序分別隸屬于未來要執行的下一條指令和下下一條指令。想到這里不禁要有個疑問,這兩個未來的指令,cpu是如何確定的?如果程序一直是順序執行的,未來無論多少條指令都可以輕易得到,都可以提前放到流水線上。可是,程序是有分支啊,到底該把哪個分支的指令放到流水線上呢?

流水線是有效提升cpu效率的方式,但流水線最大的問題是程序中的分支結構,如何把握好轉移的方向,才是使流水線保持高效的關鍵,因為如果流水線上的指令放錯了的話,必須要清空那些已經在流水線上的指令,一定不能執行錯誤的指令。隨著流水線級數越多,要清空的指令也將越多,清空流水線的代價就越大,這嚴重影響cpu效率。

當遇到一個分岔口時,是往左走還是往右走呢?對于這種分支情況,就需要預測出哪一側的指令將被執行,然后將預測出的那一分支上的指令放入流水線。從統計學的角度來看,某些事情一旦出現,下一次出現的機率還會很大。縱觀歷史,很多事情都是在重復的發生,很多偉人都拿這些歷史樣本來預測未來發生的事情。這個說的有點懸乎了,說點簡單的,比如現在是葡萄收獲的季節,今天剛吃了葡萄,很好吃,明天后天甚至未來的幾周都會繼續吃葡萄,哈哈,我大愛葡萄。

本內容摘自《操作系統真象還原》,作者不容易,請大家支持正版。

總結

以上是生活随笔為你收集整理的一步步编写操作系统 30 cpu的分支预测简介的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。