基準可讓您比較處理器,但仍有大量可變性。了解和運行標準基準可以讓設計人員更深入地了解和控制他們的應用程序。
比較微處理器從來都不是一件容易的事。即使比較通常具有相同基本架構的所有變體的處理器的臺式機或筆記本電腦也可能令人沮喪,因為與“更差”的計算機相比,具有更快數字的計算機可能運行得非常慢。在嵌入式世界中事情變得更加艱難,處理器和配置的數量實際上是無限的。
基準測試是解決這個難題的常用方法。多年來,Dhrystone 基準(對 Whetstone 基準的一種發揮,其中包括 Dhrystone 省略的浮點運算)是城里唯一的游戲。但是,它存在許多重大問題。其中最主要的是它不反映任何真實世界的計算,它只是試圖模仿各種操作的統計頻率。此外,編譯器通常可以在編譯時完成大部分計算,這意味著在運行基準測試時不必完成這些工作。
對基準的真正測試是,在詳細查看結果(尤其是那些最初看起來很奇怪的結果)時,您可以合理化為什么結果看起來如此。一個理想的基準測試將提供一個純粹反映處理器性能能力的分數,而與系統的其余部分無關。不幸的是,這是不可能的,因為沒有處理器是孤立地運行的:所有處理器都必須與內存交互——高速緩存、數據內存和指令內存,其中每一個都可能會或可能不會以完整的處理器頻率運行。此外,這些處理器必須都運行編譯器生成的代碼,不同的編譯器生成不同的代碼。
根據您在編譯代碼時選擇的優化設置,即使是同一個編譯器也會生成不同的代碼。這種差異是無法避免的,但要避免的主要事情是優化實際的基準代碼。
盡管結果可能取決于編譯器和內存,但您應該能夠僅根據處理器本身、編譯器(和設置)和內存速度來解釋任何此類結果。Dhrystone 基準測試并非如此。然而,來自嵌入式微處理器基準聯盟 (EEMBC) 的最新 CoreMark 基準已經克服了這些缺陷,并被證明更加成功。
EEMBC 于 2009 年開發并公開發布了 CoreMark 基準測試(現已有 4,100 多名用戶下載)。它已適用于包括 Android 在內的眾多平臺。開發人員特別注意避免舊基準的陷阱。通過查看 CoreMark 基準測試的工作原理以及一些示例結果,我們可以看到它不僅可以作為可靠的性能指標,還可以幫助確定微控制器和編譯器性能可以改進的地方。
CoreMark 基準測試程序
CoreMark 基準測試程序使用三種基本數據結構來表示實際工作。第一個結構是鏈表,它執行指針操作。第二個是矩陣;矩陣運算通常涉及緊密優化的循環。最后,狀態機需要難以預測的分支,并且其結構遠不如用于矩陣運算的循環。
為了讓盡可能多的嵌入式系統(無論大小)都能訪問,該程序的代碼占用空間為 2 kb。圖 1 說明了該程序的工作原理。前兩個步驟可能看起來微不足道,但它們實際上至關重要——它們是確保編譯器無法預先計算任何結果的步驟。直到運行時才知道要使用的輸入數據。

圖 1:CoreMark 基準測試流程。
大部分基準測試工作量發生在主工作循環中。掃描其中一種數據結構,一個鏈表。每個條目的值決定了要執行矩陣運算還是狀態機運算。重復此決策操作步驟,直到列表用盡。至此,單次迭代就完成了。重復工作循環,直到經過至少 10 秒。強制要求 10 秒以確保有足夠的數據提供有意義的結果。如果它運行的時間少于這個,那么基準程序將不會報告結果。但是,如果用戶在模擬器上運行基準測試,則可以修改此時間要求。
主要工作完成后,利用通用循環冗余校驗(CRC)功能;它充當自檢以確保在執行期間沒有出現任何問題(意外或其他原因)。假設一切順利,程序會報告 CoreMark 結果。這個數字表示每秒執行時間主工作循環的迭代次數。
雖然大多數基準測試用戶都是誠實的,但確保任何基準測試方案都具有防止濫用的保護措施始終很重要。有人可以嘗試篡改結果的主要方式有兩種:編輯代碼(在移植層內除外),因為代碼必須以源代碼形式提供,以及簡單地偽造結果。CRC 有助于檢測代碼損壞時可能出現的任何問題,EEMBC 技術中心的認證是最終仲裁者。沒有人需要對其結果進行認證,但認證增加了顯著的可信度,因為它確認中立的第三方獲得了相同的數字。
調整基準測試運行
雖然程序會根據用戶參數來初始化數據,但您并沒有明確提供原始數據。那將是太多的工作,而且它還可以通過仔細選擇初始化數據來進行操作。相反,程序會查找必須由用戶設置的三種子值。
這些數字以對用戶不透明的方式指導數據結構中值的初始化。雖然它們充當“種子”,但其中沒有隨機因素。這些結構是完全確定的,使用相同種子多次運行基準測試將導致相同的執行和結果。
您可能還需要調整基準以考慮系統分配內存的方式。擁有充足資源的系統可以簡單地使用 heap 和 malloc() 調用。這允許在需要時進行每次內存分配,并且準確地分配所需的內存量。然而,這種靈活性是有代價的,更好的系統需要更快的內存使用方式。
最快的方法是完全預分配內存,但使用鏈表操作是不可行的。一種中間方法是創建許多預定義的內存塊(內存池),可以根據需要分配這些內存塊。權衡是您無法選擇在每個塊中獲得多少內存——您獲得的是固定大小的塊。移植層允許您使基準測試適應被評估系統上使用的內存分配方案的類型。如果您的系統支持,并行性是您可以利用的另一個特征。您可以為并行操作構建 CoreMark 基準,指定在執行期間要生成的上下文(線程或進程)的數量。但是,您應該避免使用 CoreMark 來表示處理器的多核性能,因為這個基準測試肯定會擴展到 99。
理解結果
當然,您對基準測試結果所做的事情可能會導致混淆(有意或無意)。為此,EEMBC 提出了嚴格的報告要求。CoreMark 網站 http://www.coremark.org 有一個報告結果的地方,您不能只輸入一個 CoreMark 分數。還有一些其他關鍵變量可能會影響您的結果。
最大的是編譯基準時使用的編譯器和設置的選項。您必須在提交結果時報告該信息。
第二個主要影響因素是分配內存的方式——如果它不是堆(malloc),您必須報告所采用的方法。
相關的第三個因素是并行化。您必須報告創建的上下文數量。
還有另一種方法可以報告結果。您可以規范化時鐘頻率,而不是指定原始 CoreMark 值,以便單獨關注架構效率。這是一個 CoreMark/MHz 值,用于測量每百萬時鐘周期的迭代次數。如果您報告這個數字,那么您還必須報告相對于處理器時鐘速度的內存速度。如果可以相對于處理器頻率配置高速緩存頻率,則還必須報告該配置。
查看一些具體結果有助于了解各種所需的報告元素如何與不同的基準分數相關,以及為什么在報告結果時識別這些元素很重要。以下所有數字均來自 CoreMark 網站上的公開結果列表。
編譯器版本的簡單影響可以從表 1 的結果中看出。ADI 處理器顯示,使用較新的編譯器版本可實現 10% 的加速,這可能表明新編譯器的性能更好。Microchip 示例顯示了兩個更遠的 GNU C 編譯器 (gcc) 版本之間的更大差異。對于兩個 NXP 處理器,所有編譯器都是同一版本的細微變化,從而最大限度地減少了差異。

表 1:不同編譯器對 CoreMark 結果的影響。
即使使用相同的編譯器,不同的設置當然也會產生不同的結果,因為編譯器會嘗試以不同的方式優化程序。表 2 顯示了一些示例結果。

表 2:更改編譯器設置會產生不同的 CoreMark 結果。
在第一個示例 (PIC24JF64GA004) 中,針對更小的代碼大小進行優化是以降低大約 10% 的基準性能為代價的。第二種情況的差異更為顯著,當設置了過程抽象優化標志 (-mpa) 時,運行速度會慢 30%。最后一個處理器上編譯器設置之間的差異也反映了優化量的差異,大約 10% 受益于 –O3 設置提供的更高速度優化。
內存的影響可以在表 3 中看到。在第一種情況下,當時鐘頻率超過閃存可以處理的頻率時,會引入等待狀態,從而減少 CoreMark/MHz 數。同樣,在第二種情況下,DRAM 跟不上 50 MHz 以上的處理器,因此內存和處理器之間的時鐘頻率比下降到 1:2,降低了 CoreMark/MHz 數。

表 4:更改緩存大小對 CoreMark 結果的影響。
然而,在這兩種情況下,時鐘頻率的增加都大于運行效率的下降,因此原始 CoreMark 數字仍然隨著時鐘頻率的增加而上升;它只是沒有增加頻率。
最后,緩存大小的影響可以在表 4 中看到。這里,代碼適合第一個配置的 2 kb 緩存,但它完全填滿了緩存。堆棧上的函數參數都不適合,因此會有一些緩存未命中。在第二種情況下,緩存的容量是第一個示例的兩倍,這意味著它不會遭受與第一個示例相同的緩存未命中,從而獲得更高的分數。

表 3:內存設置對 CoreMark 結果的影響。
請注意,與第一種情況的三級管道相比,第二種情況有一個五級管道。由于狀態機示例的廣泛分支,較長的管道會導致性能下降。當分支被錯誤預測時,更長的管道需要更長的時間來重新填充。因此,較高的 CoreMark 分數表明較大的緩存足以彌補這種退化。
所有這些例子中的分數都證明了兩個事實。首先,單個數字(在本例中為 CoreMark/MHz)可以準確地表示底層微控制器架構的性能;后面的例子清楚地證明了這一點。然而,第二個事實是背景很重要。編譯器可以影響它生成的代碼的執行情況。這幾乎是顯而易見的——人們花費大量時間開發和改進編譯器來改進他們創建的結果,但“好的”結果取決于你的目標是快速代碼還是小代碼。更快的代碼會運行得更快,而更小的代碼則不會(除了那些實際上有助于優化內存或緩存利用率的情況)。
然而,這些例子顯示的最重要的事情是結果之間的差異有合理的解釋。它們不是由實際基準測試代碼的某些虛構可能導致一種微控制器架構優于另一種,或者由編譯器直接丟棄代碼引起的。從這個意義上說,CoreMark 基準測試是公平和平衡的,它真實反映了編譯器和架構,并且只反映了編譯器和架構。
評論