ARM7與CORTEX M3內(nèi)核高速度下的真實(shí)性能分析
當(dāng)有些廠家的 ARM7 內(nèi)核可以跑到75MHz 的時(shí)候,這種高速度真的讓人很興奮:32bit 的 MCU 價(jià)錢(qián)僅僅在 25 元人民幣左右,集成了各種外設(shè)的整體性能卻直逼當(dāng)年的 80486 PC 整機(jī),讓人感慨萬(wàn)千。
但是,在高速的背后,卻有些鮮為人知的細(xì)節(jié)。在看完廠家的產(chǎn)品說(shuō)明書(shū)后,有人不禁產(chǎn)生了一個(gè)疑問(wèn):集成的 MCU 真的可以跑這么快嗎?那些存儲(chǔ)器的等待周期怎么來(lái)理解呢?
----------------------------------------------------------------------------------------------------------------------------------------
在 75MHz 下,ARM7 的指令周期為 13.333ns,即 CPU 內(nèi)核每 13.333ns 內(nèi)必須要取到一條指令數(shù)據(jù)并且還要執(zhí)行完它,這就可以估計(jì)出,存儲(chǔ)器的訪問(wèn)周期大約是 6~8 個(gè)納秒左右。這樣的話,對(duì)存儲(chǔ)器的要求是非常高的,代價(jià)也是高昂的,更要命的是: 由于 FLASH 存儲(chǔ)器的生產(chǎn)工藝限制,無(wú)法達(dá)到這么快的速度!怎么辦?
為了解決這個(gè)問(wèn)題,ARM 內(nèi)核使用流水線架構(gòu),使用并行技術(shù)。例如:在執(zhí)行一條指令的同時(shí),又取出下一條指令的數(shù)據(jù),讓指令數(shù)據(jù)在執(zhí)行它之前就準(zhǔn)備好。如此一來(lái),對(duì)存儲(chǔ)器的速度要求就降低很多,按照上面的 75MHz 來(lái)說(shuō),存儲(chǔ)器的訪問(wèn)周期只要達(dá)到 13.333ns 就夠了。
對(duì)于 SRAM 存儲(chǔ)器來(lái)說(shuō),達(dá)到這個(gè)要求一點(diǎn)也不困難,但是它的工藝復(fù)雜,成本相當(dāng)高,而且一斷電就會(huì)丟失數(shù)據(jù),所以 MCU 內(nèi)的 SRAM 容量總是很小的,大多數(shù)只用來(lái)存儲(chǔ)變量數(shù)據(jù)和提供給堆棧來(lái)使用。MCU 內(nèi)又集成了不怕斷電,成本又低的 FLASH 存儲(chǔ)器,來(lái)存放程序代碼。但是 FLASH 存儲(chǔ)器是無(wú)法達(dá)到這個(gè)苛刻的速度要求的,它就是以最快的速度來(lái)運(yùn)行,訪問(wèn)周期大約也只能勉強(qiáng)提升到 30 ~ 40 多納秒左右。如此一來(lái),集成了 FLASH 存儲(chǔ)器的 ARM 內(nèi)核想要全速跑代碼還是存在問(wèn)題,如何解決呢?
各廠家不約而同地使用了一個(gè)最簡(jiǎn)易的辦法 : 拓展數(shù)據(jù)線寬度。就是將 FLASH 存儲(chǔ)器的數(shù)據(jù)線拓寬到 128bit 甚至 256bit 。這樣的話,在 FLASH 存儲(chǔ)器一個(gè)訪問(wèn)周期內(nèi),MCU 利用總線管理器可以讀取 16 個(gè)字節(jié)或 32 字節(jié)(即 4 條或 8 條 ARM 指令)的代碼數(shù)據(jù)供給 ARM 內(nèi)核執(zhí)行。這樣的話,ARM 內(nèi)核在執(zhí)行這幾條指令的期間,總線管理器可以讓FLASH 存儲(chǔ)器從容地用一個(gè)存儲(chǔ)器周期提供下 4 條或 8 條指令數(shù)據(jù),如此下去的話,似乎 ARM 內(nèi)核就可以全速跑 FLASH 中的代碼了。
這是個(gè)很巧妙的方法,但不是完美的,因?yàn)檫@種假設(shè) CPU 代碼一路跑下去不拐彎的情況在現(xiàn)實(shí)中是不存在的。各種分支、跳轉(zhuǎn)、調(diào)用等意外情況將代碼執(zhí)行順序打亂了,不可能就指望一條一條的代碼安排的整整齊齊一直順利執(zhí)行下去。
一旦出現(xiàn)這種情況,總線管理器在 FLASH 的本次訪問(wèn)周期內(nèi)提供的幾條指令數(shù)據(jù)就作廢了。為了獲得正確的下一條指令代碼,總線管理器要重新訪問(wèn) FLASH 存儲(chǔ)器的新地址。但是,由于 FLASH 本身速度的問(wèn)題,無(wú)法及時(shí)提供指令數(shù)據(jù),此時(shí)總線管理器會(huì)強(qiáng)制 ARM 內(nèi)核處于等待狀態(tài),直到 FLASH 存儲(chǔ)器完成其一個(gè)完整的訪問(wèn)周期,其中的指令數(shù)據(jù)被正確讀取出來(lái)后,總線管理器才會(huì)恢復(fù) ARM 內(nèi)核的運(yùn)行,并提供新的代碼數(shù)據(jù)給內(nèi)核執(zhí)行,這就表示本來(lái)可以跑 3~4 條指令的時(shí)間,內(nèi)核卻是被強(qiáng)制暫停的,時(shí)間被浪費(fèi)掉了,這就是存儲(chǔ)器訪問(wèn)等待周期的由來(lái)。
假設(shè)一種極端情況:FLASH 存儲(chǔ)器中的每條正常指令后面都是一條跳轉(zhuǎn)指令,那么內(nèi)核在每執(zhí)行一條指令后,就會(huì)處于等待狀態(tài)大約有 3~4 指令的執(zhí)行時(shí)間。估計(jì)一下,內(nèi)核此時(shí)的執(zhí)行速度僅僅是全速的 1/3 或 1/4 左右。如果按照主頻 75MHz 來(lái)算,此時(shí)的運(yùn)行效率大概和全速 20MHz 的內(nèi)核相當(dāng)。呵呵,很尷尬的結(jié)果,是不是?
上面假設(shè)的極端情況是極其難遇的,但是:用 C 語(yǔ)言寫(xiě)出來(lái)軟件編譯后,在 10 ~ 20 條指令里面就有一條跳轉(zhuǎn)的可能性是極高的!照此來(lái)估算的話,內(nèi)核的運(yùn)行速度比全速的低 1/10 至 1/5 左右。 按照 75MHz 的全速內(nèi)核來(lái)說(shuō),它可能僅僅只能跑到 60MHz 左右。假如軟件中采用了大量的 32bit 整型常數(shù)的話,效果和上述極端的情況是一樣的:即為了獲取當(dāng)前 FLASH 訪問(wèn)周期內(nèi)沒(méi)有的數(shù)據(jù),總線管理器必須拋棄當(dāng)前的代碼數(shù)據(jù),并重新啟動(dòng)一次訪問(wèn)周期來(lái)讀去整型常數(shù)數(shù)據(jù),然后再重新啟動(dòng)一次訪問(wèn)周期來(lái)獲得剛才被拋棄的、卻又要需要繼續(xù)執(zhí)行的代碼。
由此可以看出,軟件編寫(xiě)的好壞對(duì) ARM7 內(nèi)核的運(yùn)行效率影響是多么的巨大!
從一些廠家使用了 ARM7 MCU 為主控制器的產(chǎn)品來(lái)分析,許多需要高速運(yùn)行和需要明確指令周期的代碼段被重新加載到 MCU 中的 SRAM 中來(lái)運(yùn)行,SRAM 存儲(chǔ)器可以達(dá)到單周期訪問(wèn),即完全配合了 ARM7 內(nèi)核的高速度來(lái)全速運(yùn)行。而在更高級(jí)的 ARM 內(nèi)核中,采用了 Cache 存儲(chǔ)器,盡可能地避免上述的低效的、卻又很無(wú)奈的行為。
所以,采用了 ARM7 為內(nèi)核的 MCU ,參數(shù)表上常常標(biāo)明 SRAM 的訪問(wèn)速度為全速,等待周期為 0,而 FLASH 卻沒(méi)有明確說(shuō)明速度是多少,只是告訴你 CPU 內(nèi)核在跑到什么頻率段的時(shí)候,F(xiàn)LASH 存儲(chǔ)器的等待周期應(yīng)該設(shè)置為幾個(gè)周期,這就是原因了。
由此看來(lái),僅僅看 ARM7 的內(nèi)核運(yùn)行速度來(lái)判斷你的代碼能跑多快是不正確的。你需要分析很多綜合性的情況才能大概地了解自己寫(xiě)的代碼可以大概跑到什么速度。想要再提高,呵呵!努力吧,好好整理自己的軟件架構(gòu),來(lái)配合以 ARM7 為內(nèi)核的 MCU,這樣也許可以達(dá)到你的期望值哦!
----------------------------------------------------------------------------------------------------------------------------------------
本文是在我仔細(xì)研究了STM32 (CORTEX M3) - 32-bit Microcontrollers后有感而發(fā)的。看了廠家的宣傳是很讓人興奮,但是,仔細(xì)想想后就發(fā)現(xiàn)上述的問(wèn)題。雖然它的指令集號(hào)稱執(zhí)行效率提升到了1.25 DMIPS/MHz ,但這是僅僅純粹的內(nèi)核比較。集成到 MCU 中,就遇到了 FLASH 存儲(chǔ)器的速度問(wèn)題,而它的 FLASH 存儲(chǔ)器數(shù)據(jù)寬度是 64bit,每次就是讀取 4 條連續(xù)的指令數(shù)據(jù)。
ARM7 可以將代碼加載到 SRAM 中來(lái)全速執(zhí)行,但是 CORTEX M3卻使用了一個(gè)不同的架構(gòu),即代碼和數(shù)據(jù)分離架構(gòu),類似8051。雖然極大地降低了成本,卻帶來(lái)了不能逾越的鴻溝:代碼無(wú)法加載到 SRAM 中全速運(yùn)行。而單片機(jī)中常用的軟件架構(gòu):子程序入口表,劃分了很多細(xì)小的功能實(shí)現(xiàn)代碼段,又要查表來(lái)獲取入口地址常數(shù)、又要跳轉(zhuǎn)執(zhí)行,在 STM32 系列單片機(jī)的 FLASH 中會(huì)嚴(yán)重拖慢內(nèi)核的執(zhí)行效率。所以,這個(gè)標(biāo)稱的高速是要打很多折扣的。浮點(diǎn)運(yùn)算如果也是利用查表法在 FLASH 中搜索的話,運(yùn)行效率就可想而知了。除非哪天 STM32 在指令段也加入全速的 SRAM ,呵呵!這還有可能全速跑代碼。
因此,同頻率的 ARM7 內(nèi)核的 MCU 和 STM32 (CORTEX M3) - 32-bit Microcontrollers 進(jìn)行執(zhí)行速度比賽的話,ARM7 內(nèi)核的MCU 遠(yuǎn)遠(yuǎn)勝出。而不是那種:廣告上猛眼一看,似乎 STM32 (CORTEX M3) - 32-bit Microcontrollers 更加優(yōu)勝的結(jié)果。但是從性價(jià)比來(lái)說(shuō),ARM7 就不行了。STM32 (CORTEX M3) - 32-bit Microcontrollers簡(jiǎn)單的架構(gòu)很合適低成本的產(chǎn)品,代替 8051 是遲早的事情。
本人是看不慣廠家的廣告中,有渾水摸魚(yú)的感覺(jué),特在此撰文一述,歡迎大家指正。
我之前還沒(méi)看過(guò) LM3S6965 的資料。剛才去看了一下,它的確是將 SRAM 和 FLASH 分配在統(tǒng)一空間中的,SRAM 內(nèi)既能作為數(shù)據(jù)區(qū)使用,也可以跑代碼。這是比較自由的安排,它的這種架構(gòu)可以讓代碼全速運(yùn)行。
CORTEX M3 架構(gòu)提供了更加靈活的選擇來(lái)幫助 MCU 廠家來(lái)節(jié)省成本,既可以為成本適當(dāng)降低性能,也可以追求速度而適當(dāng)增加成本,應(yīng)該是更先進(jìn)的
評(píng)論