選擇最適處理器核心架構(gòu) 嵌入式應(yīng)用提高性價(jià)比
備份暫存器
本文引用地址:http://m.butianyuan.cn/article/201605/291453.htm圖5顯示ARMv7-M和AArch32的備份暫存器??煽闯?,許多暫存器為共有,因?yàn)檫@兩種架構(gòu)均是沿襲自ARMv6及先前的架構(gòu)。
圖5 ARMv7-M登錄集
多數(shù)指令可存取十三個(gè)通用型的暫存器r0-r12。在這兩種架構(gòu)中,r13保留為Stack Pointer(SP),r14保留為Link Register(LR),r15則保留為Program Counter(PC)。在ARMv7-M中,這些特殊暫存器的存取僅限于某些反映這些暫存器功能的特定使用狀況;在AArch32中,這些暫存器的存取則類似任何其他通用的暫存器(雖然變更Program Counter的數(shù)值可能造成非預(yù)期的副作用)。
ARMv7-M指定小部分額外特殊用途的暫存器PRIMASK、FAULTMASK、xPSR、CONTROL和BASEPRI,用于控制及設(shè)定處理器,及用于管理異常處理。
指令集
圖5與圖6分別是ARMv7-M與AArch32登錄集,兩相比較可看出AArch32也提供許多與特定作業(yè)模式關(guān)聯(lián)的暫存器。這些暫存器會在進(jìn)入相關(guān)的模式時(shí)與其在User模式下的暫存器交換。除了少數(shù)特殊指令,其他指令均無法存取這些暫存器,但也無法直接存取。其數(shù)值在模式變更時(shí)亦會保留,有助于處理異常。每個(gè)異常模式皆有自己的專屬SP,每個(gè)異常均可在獨(dú)立的堆疊上處理,因此異常處理的程式設(shè)計(jì)更為穩(wěn)固且安全。取得異常時(shí),相關(guān)模式下的LR設(shè)定為異常傳回位址。
圖6 AArch32登錄集
每個(gè)異常模式下會出現(xiàn)的還有叫SPSR的額外暫存器。SPSR用于在進(jìn)入例外時(shí)取得目前CPSR數(shù)值的快照,搭配LR使用下,可提供自動(dòng)化的內(nèi)容儲存。
AArch32圖中未顯示Mon和Hyp模式,其各自支援備份暫存器的R13和R14,如同其他的模式。
在Cortex-A中,另有一個(gè)與ARM NEON SIMD指令集(如下所述)相關(guān)的備份暫存器,共包含三十二個(gè)128位元寬度的暫存器。每個(gè)暫存器均可定址為字組、雙字組或四字組,且NEON指令集從位元組到四字組均支援向量作業(yè)。
異常模式
這兩個(gè)架構(gòu)的異常模式有相當(dāng)大的差異,兩者均支援內(nèi)部與外部異常,可由系統(tǒng)事件或外部周邊中斷所執(zhí)行。
ARMv7-M支援與傳統(tǒng)微控制器極為類似的模型,所有外部中斷分別透過包含處理常式位址的向量表來向量。
AArch32支援的模型則類似舊型ARM架構(gòu),當(dāng)中只有八個(gè)有獨(dú)立向量的異常類型。向量表包含可執(zhí)行的指令,其通常為直接連往合適的異常處理常式的分支指令。僅支援兩個(gè)外部中斷來源:FIQ和IRQ。一般只會有一個(gè)高優(yōu)先的中斷連接至FIQ,其余則連接至IRQ。亦即系統(tǒng)必須整合軟體分配器,或如同現(xiàn)代化系統(tǒng)所常見的,包含可用個(gè)別向量位址進(jìn)行程式設(shè)計(jì)的Vectored Interrupt Controller(VIC)。
許多Cortex-A系統(tǒng)包含采用ARM之Generic Interrupt Controller(GIC)架構(gòu)的標(biāo)準(zhǔn)中斷控制器。GIC可作為許多實(shí)體中斷和ARM核心的兩個(gè)中斷輸入(FIQ和IRQ)之間的介面。其可處理優(yōu)先順序的決定、遮掩、個(gè)別中斷啟用/停用和搶奪。
指令集
ARM指令集自25年前在ARM1首次推出后已經(jīng)過許多演進(jìn)。Cortex-A處理器實(shí)際上支援兩個(gè)指令集,每個(gè)指令集均有許多延伸。
.ARM指令集
ARM指令集以第一個(gè)ARM處理器所支援的原始指令集為基礎(chǔ),但已經(jīng)過多次延伸。其為load-store指令集,內(nèi)含獨(dú)立指令群組,可用于資料處理、記憶體存取、系統(tǒng)控制及控制流量?,F(xiàn)代的ARM指令集具有高效能,且范圍廣泛。此指令集中的所有指令均以固定長度的32位元字組編碼,且字組邊界必須對齊。
.Thumb指令集
Thumb指令集為ARM指令集的子集,其中每個(gè)指令均編碼為16位元的半字組,其半字組邊界必須對齊。Thumb指令集的原始概念是為了在編譯C之類的高階語言時(shí),縮小最常用指令的大小,藉此改善程式碼的密度。指令縮小后,由于指定的快取行內(nèi)可放入更多指令,因此也有助于從指令快取內(nèi)執(zhí)行。
.進(jìn)階SIMD延伸集
進(jìn)階SIMD延伸集(Advanced SIMD Extensions)亦稱為NEON,是大型的指令集,可利用延伸暫存器組合提供SIMD向量處理功能。
.向量浮點(diǎn)(VFP)
VFP指令集在與NEON相同的備份暫存器上執(zhí)行,其可提供高效能的IEEE-754相容單一與雙重精準(zhǔn)浮點(diǎn)作業(yè)。
.Thumb-2技術(shù)
Thumb-2為延伸集的名稱,在ARMv6T2(首先出現(xiàn)在ARM1156T2-S處理器)加入到Thumb指令集內(nèi)。其為混合長度的指令集,結(jié)合Thumb的程式碼密度與ARM指令集的較高效能與彈性。
假如使用者已利用Cortex-M微控制器進(jìn)行開發(fā),應(yīng)該會對Thumb-2很熟悉。這些程式碼在從最小(Cortex-M0和Cortex-M0+)到最大(Cortex-M7)的各種子集中僅支援Thumb-2。轉(zhuǎn)移到Cortex-A處理器,能為程式碼生成開啟許多可能性。
一般來說,多數(shù)針對Cortex-A處理器編譯的高階程式碼將以Thumb(含Thumb-2)為目標(biāo)。因此編譯人員可獲得最大的自由,在有多重選擇下合理選擇所要使用的指令,在針對程式碼空間進(jìn)行編譯與針對效能進(jìn)行編譯兩種情況下實(shí)現(xiàn)最高的差異。
ARM指令集通常用于必須要達(dá)到最高效能的程式碼區(qū)段。這些區(qū)段有時(shí)可在組譯器內(nèi)手動(dòng)編碼,而ARM指令集通常會是最好的選擇。
NEON指令集可用下列多種方式存取:
.有程式庫支援常見的數(shù)學(xué)與分析功能及演算法。
.編譯器支援完整的內(nèi)部功能集,允許從C直接存取完整的NEON指令集。透過這種方法,NEON作業(yè)便能以最便利的方式與C程式碼交錯(cuò)處理。
.NEON可直接在組譯器內(nèi)手動(dòng)執(zhí)行。
.編譯器亦支援反覆回路的自動(dòng)向量。只要遵循一些簡單的指示來編寫程式碼,即使是稍顯復(fù)雜的回路,編譯器也能有效執(zhí)行及向量化。
如果使用者熟悉ARMv7-A處理器,應(yīng)該也會注意到ARMv8-A加入一些額外的指令。
.密碼編譯延伸模組(Cryptographic Extensions)
這些指令為ARMv8-A新加入,目的是為了有效實(shí)作常見的加密功能建構(gòu)區(qū)塊演算法。這些延伸是在NEON備份暫存器上運(yùn)作。
.Load-Acquire和Store-Release
這些新指令符合C++11記憶體排序語法,能提升編譯效率。也可用來減少對資料側(cè)記憶體局限的需求,并部分減少與其相關(guān)的工作量。
還有一些其他與浮點(diǎn)和限制指令有關(guān)的小型延伸。
虛擬記憶體支援
支援完整虛擬記憶體環(huán)境為ARMv8-A主要功能之一,正是透過這項(xiàng)功能,這些裝置才能支援Linux和Android等平臺作業(yè)系統(tǒng)。因此,虛擬記憶體功能經(jīng)常也是在這些核心中進(jìn)行選擇時(shí)最為關(guān)鍵的條件。
虛擬記憶體環(huán)境可讓作業(yè)系統(tǒng)管理記憶體時(shí)更富彈性,像是使個(gè)別處理程序動(dòng)態(tài)延伸堆疊區(qū),啟用個(gè)別的程式碼,讓資料區(qū)能視需要在外部儲存空間內(nèi)部和外部進(jìn)行分頁,讓個(gè)別的使用者處理程序可以檢視完全相同的系統(tǒng)記憶體配置圖。
為發(fā)揮作用,虛擬記憶體在處理器所配發(fā)的每個(gè)位址上加入了“轉(zhuǎn)譯”,如圖7所示。軟體會在“虛擬位址空間”執(zhí)行,還有一個(gè)名為記憶體管理單元的區(qū)塊會將其轉(zhuǎn)譯為實(shí)體位址空間。
圖7 虛擬記憶體
為了使作業(yè)系統(tǒng)完整控制存取權(quán)限等內(nèi)容,以針對系統(tǒng)內(nèi)的各項(xiàng)使用者工作及作業(yè)系統(tǒng)本身建立新的虛擬記憶體配置圖。每項(xiàng)工作可當(dāng)作系統(tǒng)內(nèi)唯一的工作,在自己的虛擬記憶體空間內(nèi)執(zhí)行。只有作業(yè)系統(tǒng)知道工作程式碼及資料區(qū)在外部實(shí)體記憶體內(nèi)的實(shí)體位置。
在切換工作時(shí),作業(yè)系統(tǒng)的其中一項(xiàng)任務(wù)就是重新設(shè)定記憶體管理單元,以啟用傳入工作所用的程式碼及資料,同時(shí)讓傳出工作的記憶體暫時(shí)無法存取。如此可強(qiáng)制區(qū)分工作,為安全且彈性的系統(tǒng)的必要元素。
此處不會提供完整說明,ARM處理器內(nèi)的記憶體管理單元使用保留在外部記憶體中的“分頁表”所含的資料來帶動(dòng)及控制轉(zhuǎn)譯。系統(tǒng)整合多項(xiàng)最佳化作業(yè)(例如,包含Translation Lookaside Buffers,或簡稱為TLB,能為最近使用過的轉(zhuǎn)譯建立快取,以減少讀取分頁表的工作量),可盡量縮小轉(zhuǎn)譯處理程序的工作量。
從ARMv7-M到ARMv7-A的軟體轉(zhuǎn)移
多數(shù)的高階軟體皆須要簡單的重新編譯。下列區(qū)域的軟體則須詳加注意:
.重置程式碼及其他例外處理常式
如果使用作業(yè)系統(tǒng),這部分的工作將由作業(yè)系統(tǒng)所提供的工具來處理。多數(shù)情況下,常見作業(yè)系統(tǒng)的連接埠將透過公開網(wǎng)域散布或裝置供應(yīng)商提供。
因異常模式差異較大,因此須重新寫入中斷處理常式。作業(yè)系統(tǒng)同樣會提供基礎(chǔ)架構(gòu)來完成這部分工作,藉以簡單地重新編譯多數(shù)中斷處理常式的主體。
.周邊驅(qū)動(dòng)程式
從RTOS轉(zhuǎn)移到Linux這類的多功能平臺作業(yè)系統(tǒng)時(shí),應(yīng)用程式碼及周邊驅(qū)動(dòng)程式須更明確地加以區(qū)隔。
.系統(tǒng)組態(tài)功能
采用Cortex-M與Cortex-A的裝置在提供系統(tǒng)組態(tài)與控制功能存取方面有較大的差異。Cortex-M處理器通常透過具名或記憶體對映的暫存器來設(shè)定,可直接讀取及寫入,以達(dá)成所要的功能。Cortex-A處理器(為Cortex-A32所支援的AArch32執(zhí)行狀態(tài))則是透過“系統(tǒng)控制協(xié)同處理器”來支援設(shè)定。概念性的“協(xié)同處理器15”包含大量的設(shè)定暫存器集,使用專屬的指令進(jìn)行讀取及寫入。非由作業(yè)系統(tǒng)執(zhí)行的系統(tǒng)組態(tài)功能則須重新寫入,以完成這部分的工作。也就是說,作業(yè)系統(tǒng)通常會提供應(yīng)用程式介面(API),以用于須要由使用者介面存取的功能。
.匯編程式碼
很明顯地,匯編程式碼也須特別注意。因?yàn)閷懭雲(yún)R編程式碼的其中一個(gè)主要原因,便是為了獲得最高的效能,因此必須詳加檢驗(yàn)這些功能,確定重新寫入能在存取NEON等某些延伸指令集功能時(shí)提供好處。若舊型的匯編程式碼已使用“Uniform Assembler Language(UAL)”語法寫入,則多數(shù)程式碼將簡單地重新匯編為ARM或Thumb指令。
評論