性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

  • 回復
  • 收藏
  • 點贊
  • 分享
  • 發(fā)新帖

ARM的一些探討

ARM經歷了幾十年的發(fā)展,其核心架構已經從最初商用的ARMv4發(fā)展到了如今的ARMv7,據(jù)說ARMv8正處于開發(fā)之中,各個版本的內核大同小異,掌握了ARM的思想,其實看著都差不多,就是可配置模塊不太一樣,或者在指令集,實現(xiàn)方式上做些改變,從軟件工程師的角度來看,基本都是一樣的,當然如果你是做驗證級別的軟件工程師,還是要掌握非常細節(jié)的部分。

 

在ARM的官方文檔中,對RISC的特性描述如下(當然ARM也都實現(xiàn)了):

1.     較大的寄存器文件(換句話說就是有較多的通用寄存器)

2.     load/store架構,就是所有除load/store的數(shù)據(jù)操作都是在寄存器之間完成,不能夠對內存中的數(shù)據(jù)直接進行。寫過單片機程序的人應該有體會,51,96這些都是可以直接對內存中的數(shù)進行數(shù)學操作的。

3.     簡單地尋址模式,所有的load/store地址都是通過寄存器內容和指令算出來的。這點也是區(qū)別于CISC的復雜尋址模式,總之就是一條,什么事都盡量交給寄存器。

 

  ARM還對基本的RISC架構進行了如下擴展:

1.    增加了算術移位指令

2.    地址自增和地址自減模式以優(yōu)化循環(huán)操作

3.    多重load/store指令以增大數(shù)據(jù)處理速度

4.    幾乎所有指令都是可以條件執(zhí)行的,以增加指令處理速度。

 

  關于ARM到底屬于什么類型的CPU,一直以來說法不一,有說他們是RISC(至少他們自己這么認為,公司名字就是Advanced RISC Machines的簡寫)。

  有說他們是類RISC的,說他們是類RISC的理由是ARM的指令并不是定長的,而且并沒有實現(xiàn)真正的流水線。當然這些區(qū)別現(xiàn)在已經變得越來越不重要,甚至各領域之間也在互相滲透,比如MIPS的14K和24K系列也已經引入了16位的指令,支持16/32位指令(ARM/THUMB interworking)混編,而較新的ARM架構中也已經實現(xiàn)了對亂序執(zhí)行的支持。

可能有人會反駁,怎么可以這么說ARM沒有實現(xiàn)流水線呢?ARM7中就已經實現(xiàn)了三級流水線!請注意,這里所說的是真正的流水線,如果對MIPS有所了解或者看過MIPS陣營的經典著作《See MIPS Run》,再結合AMBA文檔中對AHB和APB的描述,就能明白真正的流水線的含義。下面我們先對其他架構的流水線結構做一個分析。

提到流水線就要了解一個概念叫做delay slot,也就是我們所說的延遲槽,出現(xiàn)這個概念的原因是因為在RISC中,絕大多數(shù)指令的執(zhí)行時間是可預測的,一般為一個時鐘周期。而有些指令譬如load,jmp之類的指令無法在一個周期內完成,這樣就造成一個問題,在執(zhí)行jmp,load時,處于譯碼階段的指令就要多等一個周期,等前面的指令執(zhí)行結束它才能進入執(zhí)行階段(早期的ARM就是采用這種方式)。而在真正的流水線架構中,遇到這種情況,可以把jmp,load之后的指令在jmp,load進入執(zhí)行階段準備,但是沒有真正執(zhí)行的時候提前執(zhí)行,這樣就節(jié)省了之前被浪費的那個周期。處于延遲槽中被提前執(zhí)行的指令必須是對后續(xù)指令無害的,有害還是無害一般是由編譯器來決定,判斷有害還是無害的標準主要是看延遲槽中的指令結果是否和它前面的指令有關聯(lián),當無法插入無害指令時,編譯器會向其中插入NOP。千萬不要小看這一個周期,因為在真正的軟件系統(tǒng)運行過程中,內存讀寫以及跳轉操作隨處可見,所占的比例相當大,就這一點點效率的提升就導致了MIPS在整數(shù)運算性能上的優(yōu)勢,即使是在如今ARM如此盛行的時代,高端的路由器交換機以及大型圖形服務器等依然還是MIPS占據(jù)優(yōu)勢(情況可能有變,ARM已經收購了MIPS的64位技術)。

個人曾經遇到過幾次關于延遲槽的陷阱,舉一個最近的例子來說,在MIPS的bootloader中,一般會在匯編代碼前有.set noreorder選項,也就是禁止編譯器將代碼按照編譯器所認為的優(yōu)化執(zhí)行順序重新排序,這主要是因為bootloader相對敏感,并且對那么幾行代碼重排序也沒必要。在bootloader中有一段代碼拷貝的地方:

1:  addui t1,4

    Addui t2,4

    Sw  t1,[t2]

    Jne t2,t4,1b

    Mfl t2,$14

麻煩就出在了最后一句,按照順序思維,應該是執(zhí)行完了循環(huán)再執(zhí)行它,可是由于他在延遲槽中,每次循環(huán)都會去執(zhí)行它,于是修改了t2的值,造成了地址錯誤的異常。在ARM中你就不用擔心這個陷阱,因為ARM沒有延遲槽一說,該等你就得等…。

而支持ARM屬于RISC的理由主要在于四點:

1. 使用了精簡指令集,Reduced Instruction Set Computer,雖然ARM的指令相對其他種類的RISC架構核心來比較還是算多的,但畢竟處于可接受范圍,不像x86架構那樣不斷添加各種指令,浩瀚無窮。RISC的宗旨就是讓硬件盡量簡單,更多的處理交給編譯器和軟件,這樣就可以讓cpu的核心結構更加簡單,比較容易實現(xiàn)低功耗高頻率。

2. 實現(xiàn)了一定程度的流水線,學過51的人應該還記得51的工作方式,指令都是一條一條地取指,譯碼,執(zhí)行,只有上一條指令執(zhí)行結束,下一條指令才能進入取指階段。也就是說cpu在相當長一段時間內只能為一條指令服務,而在RISC架構中,每一時刻基本都會有幾條指令處于不同的階段。

3.ARM核心中有較多的通用寄存器,其數(shù)目為31個(不算狀態(tài)寄存器),要比CISC的通用寄存器數(shù)目多很多。但是這31個寄存器并不是同時存在的,有些寄存器是模式專有的,只有處理器處于那種模式才能夠對其進行操作,術語稱為Banked,在某種模式下可見的通用寄存器的個數(shù)是16個。

4.采用了Load-Store的工作方式,所謂的Load-Store方式,也就是說一切的計算操作都只針對寄存器,內存中的數(shù)據(jù)需要先load到寄存器,在寄存器中進行計算之后再store回內存。而在CISC中,內存數(shù)據(jù)是可以直接參與計算的,這是雙方一個巨大的差別。

 

全部回復(1)
正序查看
倒序查看
xinzha
LV.1
2
2014-03-20 22:25

通常來說軟件人員并不關心流水線的細節(jié),尤其是上層軟件程序員,甚至驅動工程師都不需要了解流水線,但是對于一個真正的系統(tǒng)底層工程師來說,了解流水線的一個比較重要的意義就是當出現(xiàn)問題時,能夠精確定位到產生問題的那條指令,從而精確跟蹤問題,還有就是異常處理程序執(zhí)行完成后根據(jù)LR寄存器的值來正確返回也需要對流水線的了解。不過有些情況下體制就不能保證精確定位,比如說有write buffer的時候,你的寫指令即使會發(fā)生錯誤(例如地址錯誤、權限錯誤、器件錯誤等),也是在數(shù)個周期之后,當寫指令真正出現(xiàn)在總線上時才會激起異常,其原因是因為速度匹配問題,寫數(shù)據(jù)需要通過write buffer來完成,發(fā)生異常的時刻已經離發(fā)出寫指令的時刻不匹配了。

當發(fā)生異常的時候,犯罪分子和發(fā)生異常時所在模式的pc的匹配關系如下:

Data abort pc - 8,因為data abort只有進入執(zhí)行階段才能被發(fā)現(xiàn),這時第三條指令已經被取指。IRQ pc - 8,IRQ發(fā)生時刻不可預知,在當前指令執(zhí)行完之后響應,所以pc也是第三條的地址。FIQ pc - 8,原理同上。Prefetch Abort pc - 4,這個最繞,是預取指時發(fā)生錯誤造成的,但是如果這條指令不進入執(zhí)行階段就不會造成異常,比如說前面一條是jmp。所以我猜測在它進入執(zhí)行之前,kernel已經知道出錯,pc不再更新,保持為它下一條指令的位置。

SWI和UNDEF和上一條一樣,都是在譯碼階段kernel已經知道會發(fā)生異常,不再更新pc,但是進入執(zhí)行階段才會激起異常,所以異常地址也都是pc-4。

今天來討論一下對齊問題,在ARM7,即arm v4中,規(guī)定如果訪問int類型數(shù)據(jù)時給出的指針地址的低2位不為0的話,系統(tǒng)會自動將低兩位的1抹平,即強制四字節(jié)對其,這樣的問題就是如果你的數(shù)據(jù)偏偏就是不對齊的,cpu拿到的數(shù)據(jù)就是不正確的,bug由此產生。在ARM9(我接觸的是arm926ejs)中,如果訪問int型數(shù)據(jù),低2位不為0,那么cpu直接掛住,一個data abort。在ARM11之后的版本中支持了非對齊訪問,是在總線上拆分然后拼接來實現(xiàn)的,也就是說如果你訪問int時給出的地址不是4字節(jié)對齊,那么總線上會出現(xiàn)兩個int訪問,然后把數(shù)據(jù)拼接起來送給cpu,這些對于cpu是不可見的,但是會導致速度下降,總線占用率上升。此功能可以通過修改cp15中來關閉,實現(xiàn)跟以前版本一樣的對齊方式。需要說明的是這里的int是4字節(jié)而不是2字節(jié)。另外一點是對齊問題并不是專指四字節(jié)對齊,很多初學者或者有一定經驗的人都會犯這個錯誤,認為只有四字節(jié)對齊才會出問題。實際上對齊指的是數(shù)據(jù)邊界對齊,也就是說long long數(shù)據(jù)要8字節(jié)對齊,int要4字節(jié)對齊,short要2字節(jié)對齊,byte自然是怎么對都齊了。

 

0
回復
發(fā)