日韩在线不卡免费视频一区,日韩欧美精品一区二区三区经典,日产精品码2码三码四码区,人妻无码一区二区三区免费,日本feerbbwdh少妇丰满

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

ARM的一些探討

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

 

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

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

2.     load/store架構(gòu),就是所有除load/store的數(shù)據(jù)操作都是在寄存器之間完成,不能夠?qū)?nèi)存中的數(shù)據(jù)直接進(jìn)行。寫過單片機(jī)程序的人應(yīng)該有體會,51,96這些都是可以直接對內(nèi)存中的數(shù)進(jìn)行數(shù)學(xué)操作的。

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

 

  ARM還對基本的RISC架構(gòu)進(jìn)行了如下擴(kuò)展:

1.    增加了算術(shù)移位指令

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

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

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

 

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

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

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

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

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

1:  addui t1,4

    Addui t2,4

    Sw  t1,[t2]

    Jne t2,t4,1b

    Mfl t2,$14

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

而支持ARM屬于RISC的理由主要在于四點(diǎn):

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

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

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

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

 

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

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

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

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

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

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

 

0
回復(fù)
發(fā)