2010年6月18日 星期五

在NUC501上測定程式效能

前次修改了ROM虛擬記憶體的演算法之後,雖然可以感覺到程式執行的速度有所提昇,但目測可能會隨著時間、身心狀態的不同,而使得結果誤差很大,所以著實需要能客觀測定程式改進幅度的機制,以免陷入程式愈改愈遭的命運!

使用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. 測試的時間為1秒。
  2. 以ROM虛擬記憶體的方式執行,在測試時間內重複呼叫DrvSDCard_Read函式,測試時每次讀取1 sector,每讀取一次將計數器加一。
  3. 時間到時將計數器的值除以2即可得到每秒讀取速度。

測試完畢後,得到DrvSDCard_Read函式至少有516K/sec的傳輸速率。雖然一次讀取多個sector可能會得到更好的結果,但為了節省記憶體,APSLib內的快取只有一個sector的長度,所以單測一個sector才能知道底層運作的效能如何,不過有這樣的速率應該不會拖慢RAM虛擬記憶體太多呀~~接下來就來測試ASPLib模擬的fread,同樣測試條件如下:

  1. 測試的時間為1秒。
  2. 以ROM虛擬記憶體的方式執行,在測試時間內重複呼叫fread函式,測試時每次讀取512 bytes,每讀取一次將計數器加一。
  3. 時間到時將計數器的值除以2即可得到每秒讀取速度。
最後得到令人難堪的12K/sec!天啊!難怪RAM虛擬記憶體的效能如此低落!看來問題有得找了。


後記:

為了得知效能增進的幅度,另外也重做了第一項測試,但改為不使用ROM虛擬記憶體,而將程式完全放在SpiROM下執行,看看虛擬記憶體這東西到底有沒有效果!值得欣慰的是,得到了38K/sec的執行結果,幸好這大半年東搞西搞的還是有代價的(泣),不然就要被我自己毆飛了。

沒有留言:

張貼留言