使用ICE的人,可能早就使用profile取得程式的效率報告了,不過在開發環境是台拼裝車,加上程式執行的方式被改到亂糟糟的情況下,即使有ICE恐怕也無法正確取得所要的效能資料,另外我們也需要一個能讓程式delay正確的時間,而不受處理器速度影響的方法。
以前使用8-bit微處理器的時候,因為timer精度的關係,這類的需求通常是撰寫timer中斷,設定想要的中斷時間間隔,然後在每次中斷時將計數值加一,雖然可用,但當需要測定的時間精度很高時,恐怕沒有多少處理器可以承受這麼高速的中斷。
在NUC501上,timer是屬於AIC的管轄範圍,這部份因個人因素(哈),暫時還不想去處理,也不希望因使用中斷,讓目前還不知道效能問題出在哪的情況雪上加霜。另外,目前的開發流程主要是先在PC上進行,等階段功能完成之後,才移植到NUC501上去測試,使用中斷會使程式的移植性降低。
在PC上,可以透過SDL系統的SDL_GetTicks()函式(對應於Windows的GetTickCount())取得32-bit的系統Ticks值,時間精度為1ms,最長可以測到49.71天,所以如果程式跑得很慢,49.71天也真夠測得了(笑)。而在NUC501上,也裝備二組32-bit的timer可以提供類似的功能,但時間精度更高,如果使用「NUC501 IP Programming Guide」文件內的建議值,可以得到1us的Tick值,不過這麼一來最長測定時間只有4294.97秒(約71.58分鐘)。
不過為了與電腦的互換性,還是得忍痛降低精確度,方法是將Tick值除以1000就可以了。但因為ARM7TDMI沒有除法指令,使用除法會使得系統呼叫專門處理除法的函式庫,反而拖慢執行速度,所以希望可以簡單用shift的方式來達成。
以目前系統所使用的12MHz Crystal來看,利用TCSRx暫存器的PRESCALE,可以將Crystal除頻到接近64000Hz上,這樣既可以用shift處理又可延長量測時間,雖然有一點偏差,但還可接受,最長的量測時間就爆增到18.64小時了呢!
有了時間測定的功能之後,就可以測程式的效能了,由於RAM虛擬記憶體的效能不佳,所以先來測試SD卡的讀取效率吧!
測試的條件如下:
- 測試的時間為1秒。
- 以ROM虛擬記憶體的方式執行,在測試時間內重複呼叫DrvSDCard_Read函式,測試時每次讀取1 sector,每讀取一次將計數器加一。
- 時間到時將計數器的值除以2即可得到每秒讀取速度。
測試完畢後,得到DrvSDCard_Read函式至少有516K/sec的傳輸速率。雖然一次讀取多個sector可能會得到更好的結果,但為了節省記憶體,APSLib內的快取只有一個sector的長度,所以單測一個sector才能知道底層運作的效能如何,不過有這樣的速率應該不會拖慢RAM虛擬記憶體太多呀~~接下來就來測試ASPLib模擬的fread,同樣測試條件如下:
最後得到令人難堪的12K/sec!天啊!難怪RAM虛擬記憶體的效能如此低落!看來問題有得找了。
- 測試的時間為1秒。
- 以ROM虛擬記憶體的方式執行,在測試時間內重複呼叫fread函式,測試時每次讀取512 bytes,每讀取一次將計數器加一。
- 時間到時將計數器的值除以2即可得到每秒讀取速度。
後記:
為了得知效能增進的幅度,另外也重做了第一項測試,但改為不使用ROM虛擬記憶體,而將程式完全放在SpiROM下執行,看看虛擬記憶體這東西到底有沒有效果!值得欣慰的是,得到了38K/sec的執行結果,幸好這大半年東搞西搞的還是有代價的(泣),不然就要被我自己毆飛了。