Coremark は EEMBC で配布されている、無料のCPU性能測定ベンチマークだ。 複数のアプリケーションセットで構成されており、ITERATION回数を指定して特定秒数の間に何回イタレーションを回せるかで性能が決定される。 また、クロック周波数に依存した値だけでなく、クロック周波数で割って、1サイクルあたりの性能を出すCMK/MHz も一般的に使われている。
ちなみにCoremarkの詳細はオフィシャルホームページを参照のこと。
http://www.eembc.org/techlit/coremark-whitepaper.pdf
ちなみに代表的なプロセッサのCoremark/MHzの値。
組み込み向けではルネサスのRXが意味分かんないくらい突出している。3.0を越えれば良いくらいの感じかな。 ちなみにPrescottを載せたのは、高いCPUは必ずしも高いサイクル性能を出せている訳ではないということ。周波数で稼いで、パイプライン長くしてるんだからしょうがないよね。
というわけで、Cortex-A9が乗っているZedBoardでCoremarkを動作させた。 EEMBCのホームページからCoremarkをダウンロードし、SDKにプロジェクトを作る。 移植用のファイル core_portme.c と core_portme.h を変更する。特に必要なのはサイクルを測定する部分。これにはZynqのタイマーを利用する。 このあたりのテクニックは、
Zynq design from scratch. Part 15. « New Horizons Zynq Blog
をめちゃくちゃ参考にさせてもらった。すごいやこの人。
ee_u32 GetTimerValue(ee_u32 TimerIntrId,ee_u16 Mode) { int Status; XScuTimer_Config *ConfigPtr; volatile ee_u32 CntValue = 0; XScuTimer *TimerInstancePtr = &Timer; if (Mode == 0) { // Initialize the Private Timer so that it is ready to use ConfigPtr = XScuTimer_LookupConfig(TimerIntrId); Status = XScuTimer_CfgInitialize (TimerInstancePtr, ConfigPtr, ConfigPtr->BaseAddr); if (Status != XST_SUCCESS) { print ("XST_FAILURE\n"); return XST_FAILURE; } // Load the timer prescaler register. XScuTimer_SetPrescaler (TimerInstancePtr, TIMER_RES_DIVIDER); // Load the timer counter register. XScuTimer_LoadTimer (TimerInstancePtr, TIMER_LOAD_VALUE); // Start the timer counter and read start value XScuTimer_Start(TimerInstancePtr); CntValue = XScuTimer_GetCounterValue (TimerInstancePtr); } else { // Read stop value and stop the timer counter CntValue = XScuTimer_GetCounterValue (TimerInstancePtr); XScuTimer_Stop(TimerInstancePtr); } return CntValue; }
最初HAS_TIME_Hディレクティブを有効にしていて全然時間が合わなかったが、修正すると何とかあった。 SAMPLE_TIME_IMPLEMENTATIONを1にして、start_time()、stop_time()とかを編集する。 オリジナルのもとの酷似させたまま編集したので、↑の参考ページのものと比べると多少diffが取りやすいかもしれない。これはそのうちgithubに上げる。
コンパイル時にはディレクティブもいろいろ設定が必要。
実行結果:
2K performance run parameters for coremark. CoreMark Size : 666 Total ticks : 209493933 Total time (secs): 25.126709 Iterations/Sec : 1989.914429 Iterations : 50000 Compiler version : GCC4.8.3 20140320 (prerelease) Compiler flags : -O3 Memory location : Please put data memory location here (e.g. code in flash, data on heap etc) seedcrc : 0xe9f5 [0]crclist : 0xe714 [0]crcmatrix : 0x1fd7 [0]crcstate : 0x8e3a [0]crcfinal : 0xa14c Correct operation validated. See readme.txt for run and reporting rules. CoreMark 1.0 : 1989.914429 / GCC4.8.3 20140320 (prerelease) -O3 / Stack
1989 / 666(MHz) をすると2.98 なので、概ね公称値が出せている。