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