關於程序計數器(PC)和條件控制轉移 引起的性能差異


關於PC(程序計數器)

馮 ·諾伊曼計算機體系結構的主要內容之一就是“程序預存儲,計算機自動執行”! 
處理器要執行的程序(指令序列)都是以二進制代碼序列方式預存儲在計算機的存儲器中,處理器將這些代碼逐條地取到處理器中再譯碼、執行,以完成整個程序的執行。 
為了保證程序能夠連續地執行下去,CPU必須具有某些手段來確定下一條取指指令的地址。

程序計數器(PC )正是起到這種作用,所以通常又稱之為‘指令計數器’。CPU總是按照PC的指向對指令序列進行取指、譯碼和執行,也就是說,最終是PC 決定了程序運行流向。故而,程序計數器(PC )屬於特別功能寄存器范疇,不能自由地用於存儲其他運算數據。

1、在程序開始執行前,將程序指令序列的起始地址,即程序的第一條指令所在的內存單元地址送入PC, 
2、CPU按照PC的指示從內存讀取第一條指令(取指)。 
3、當執行指令時,CPU自動地修改PC的內容,即每執行一條指令PC增加一個量,這個量等於指令所含的字節數(指令字節數),使PC總是指向下一條將要取指的指令地址。 
4、由於大多數指令都是按順序來執行的,所以修改PC的過程通常只是簡單的對PC 加“指令字節數”。但是,當遇到轉移指令如JMP(跳轉、外語全稱:JUMP)指令時,后繼指令的地址(即PC的內容)必須從指令寄存器中的地址字段取得。在這種情況下,下一條從內存取出的指令將由轉移指令來規定,而不像通常一樣按順序來取得。因此程序計數器的結構應當是具有寄存信息和計數兩種功能的結構。

5、當程序轉移時,轉移指令執行的最終結果就是要改變PC的值,此PC值就是轉去的目標地址。 
6、處理器總是按照PC指向,取指、譯碼、執行,以此實現了程序轉移。

總之:在CPU控制部件中的程序計數器(PC)的功能是用於存放指令的地址。程序執行時,PC的初值為程序第一條指令的地址,在順序執行程序時,控制器首先按程序計數器所指出的指令地址從內存中取出一條指令,然后分析和執行該指令,同時將PC的值加1指向下一條要執行的指令


處理器通過使用流水線來獲得高性能,在流水線中,一條指令的處理要經過一系列的階段,每個階段執行所需操作的一小部分(例如,從內存取指令、確認指令類型、從內存讀數據、執行算數運算、向內存或者寄存器寫數據、以及更新程序計數器),在取一條指令時候,他可能同時在進行對上一條指令的算術運算。

第五條說明在你用條件控制轉移的時候,最終結果就是要改變的PC的值,這么說的話,要等到條件控制轉移相關指令執行完畢后才能決定下一條指令的地址。
對於這種情況處理器采用非常精密的分之預測邏輯來猜測每條跳轉指令是否會執行(如果不判斷的話,就百分百會損失這部分效率)。錯誤預判會招致處理器丟掉它為該跳轉指令后的所有指令已做的工作,然后從正確的位置起始的指令填充流水線。大概會浪費15~30個時鍾周期!!

但是如果把條件控制轉移換成條件數據傳送的話,就能避免錯誤判斷帶來效率損失。不論是否傳送條件,都不影響他后面的指令進流水線。

舉個例子:

long absdiff(long x, long y)
{
  long result;  

  if(x < y)
    result = y - x;
  else
    result = x - y;
  return result;
}

如果我用gcc -O1 來編譯

他直接用了comvl指令來代替jump

注意,程序前面已經把a-b和b-a都求出來了,即先求出條件操作的兩種結果,然后再根據條件是否滿足從而選取一個。 (錯錯錯)
兩個都求出來了,把一種放入%rax,然后根據條件是否滿足來決定是否更新為另外一種或者保持不變。
總之,條件傳送指令使得控制流不依賴於數據(關鍵是沒了jump,不用預測,也可以照常讓后面的指令進流水線),流水線也更容易保持滿狀態。  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM