CoreMarkでRaspberry Pi Picoのベンチマークを取る
前回、書いたばかりですがDhrystoneはいささか古くて時代遅れらしいので(中身が解析されきっていてDhrystoneに最適化されやすい(しているかはともかく)、CPUのベンチマークというよりコンパイラーのベンチマークになってしまっている、など)、CoreMarkというベンチマークを使ってみます。
CoreMark ダウンロード & プロジェクト構築
開発環境は前回と同様にWindows10とRaspberry Pi 2BをSSHで接続してWindows10上のVSCodeで開発します。
Raspberry Pi 2BとRaspberry Pi PicoとはUSBもしくはSWDで接続して実行ファイルを書き込みます。
CoreMarkのスコアのサイトで多くのCPUのベンチマークが閲覧できますが、残念ながらRP2040に関してはなかったので実装してみました。
CoreMarkのコードはGitHubからダウンロードできます。
1 |
=/pico_exam $ git clone https://github.com/eembc/coremark.git |
できたcoremarkディレクトリーのcoremark/barebones/core_portme.cおよびcoremark/barebones/core_portme.hをcoremarkディレクトリー直下にコピーします。
1 |
~pico_exam/coremark $ cp barebones/core_portme.c barebones/core_portme.h . |
対象環境に合わせて、「linux」「macos」などのディレクトリー下の”core_portme.c”、”core_portme.h”をそれぞれ使うと思うのですが、今回は「barebones」ディレクトリーでいいと思います(もしくは「simple」ディレクトリー)。
さらにcoremarkディレクトリーに、前回の「DhrystoneでRaspberry Pi Picoのベンチマークを取る」と同様に”CMakeLists.txt”を追加します。
8 9 10 11 12 13 14 15 16 17 18 19 20 |
pico_sdk_init() add_executable(coremark core_main.c core_list_join.c core_matrix.c core_state.c core_util.c core_portme.c ) pico_enable_stdio_usb(coremark 0) pico_enable_stdio_uart(coremark 1) |
前回の「DhrystoneでRaspberry Pi Picoのベンチマークを取る」と大体同じです。
そして前回と同様に”pico_sdk_import.cmake”ファイルをコピーします。
1 |
~/pico_exam/coremark $ cp ~/pico/pico-sdk/external/pico_sdk_import.cmake . |
コード修正
コード修正は”core_portme.h”と”core_portme.c”のみに行います。
まず”core_portme.h”です。
”#define HAS_STDIO”と”define HAS_PRINTF”を0→1に変更します。
47 48 49 50 51 52 53 54 55 56 57 58 59 |
/* Configuration : HAS_STDIO Define to 1 if the platform has stdio.h. */ #ifndef HAS_STDIO #define HAS_STDIO 1 #endif /* Configuration : HAS_PRINTF Define to 1 if the platform has stdio.h and implements the printf function. */ #ifndef HAS_PRINTF #define HAS_PRINTF 1 #endif |
“COMPILER_FLAGS”を定義します(buildを通すためだけで内容に意味はないと思われます)。
71 72 73 74 |
#ifndef COMPILER_FLAGS #define COMPILER_FLAGS "-o3" // FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */ #endif |
headerファイルをいくつかincludeします。
86 87 88 89 |
*/ #include <stdlib.h> #include "pico/stdlib.h" #include "pico/time.h" |
“size_t”を”uint32″に変えます。
97 98 99 |
typedef ee_u32 ee_ptr_int; typedef /*size_t*/uint32_t ee_size_t; #define NULL ((void *)0) |
次に”core_portme.c”を何箇所か変更します。
“ITERATIONS”を指定します。今回は10,000にしました。
35 36 37 |
#endif #define ITERATIONS 10000 volatile ee_s32 seed4_volatile = ITERATIONS; |
barebones_clock()関数の#errorをコメントアウトして定義を追加します。
get_absolute_time()はpico-sdkで提供されている関数になります。
45 46 47 48 49 50 51 |
CORETIMETYPE barebones_clock() { // #error \ // "You must implement a method to measure time in barebones_clock()! This function should return current time.\n" return (CORETIMETYPE)get_absolute_time(); } |
“CLOCKS_PER_SEC”を定義します。
59 60 |
*/ #define CLOCKS_PER_SEC 1000000.0 |
portable_init()関数の先頭の#errorをコメントアウトしてprintfが機能するように”stdio_init_all()”関数を追加します。
132 133 134 135 136 137 |
void portable_init(core_portable *p, int *argc, char *argv[]) { // #error \ // "Call board initialization routines in portable init (if needed), in particular initialize UART!\n" stdio_init_all(); |
RP2040はdualコアですが、今回はシングルコアのベンチマークです。
dualコア対応にするには#define MULTITHREAD を2にして呼び出される関数をpico関数の”multicore_launch_core1(some_function_pointer);”などにすればいいかなと思いますが、私にとっては中々難しいのとそれによって得られた結果が正しいのかあまり自信がないのでシングルコアにみにしました。
build & 実行
これで準備ができたので”make”します。
1 2 3 4 |
~pico_exam/coremark/ $ mkdir build ~pico_exam/coremark/ $ cd build ~pico_exam/coremark/build $ cmake .. ~pico_exam/coremark/build $ make -j4 |
前回は”BOOTSEL”ボタンを押しながらPicoに電源投入するとPicoが大容量ディスクとして認識されるのでそのディスクに書き込んでいましたが、OpenOCDをインストールしてありSWD配線がされていればコマンドにて書き込めます。
Raspberry Pi | Raspberry Pi Pico |
GND(Pin 20) | SWD GND |
GPIO24(Pin 18) | SWDIO |
GPIO25(Pin 22) | SWCLK |
以下のコマンドで書き込めます。
1 |
~pico_exam/coremark/build $ openocd -f interface/raspberrypi-swd.cfg -f target/rp2040.cfg -c "program coremark.elf verify reset exit" |
書き込まれるとCoreMarkプログラムが走り出しますので結果をシリアルモニターで確認します。ITERATIONS=10,000ならCoreMarkプログラム実行に40秒ほどかかるので、プログラム書き込みをしたターミナルと同じターミナルでシリアルモニターを起動してもいいですし、別ターミナルで事前にシリアルモニターを起動しておいてもいいです。
1 |
$ minicom -b 115200 -o -D /dev/serial0 |
結果 & 比較
結果は以下のとおりです。
CoreMark 246.50、CoreMark/MHz = 1.85 となりました。
CoreMark.orgのScoresでは前回のDhrystoneで比べてたSTM32F411はありませんが近いところでSTM32F417を見てみます(Processor Name Matchに”STM32F”と入れて「Apply Filter」ボタンをクリック)。
コンパイラーの違いなどで複数の結果がありますが一番数字の大きいところでCoreMark 565.73、CoreMark/MHz 3.37とあります。
あとExpressif ESP32も見てみるとCoreMark 660.70、CoreMark / MHz 4.13とあります。
picoも2個のコアをフルに使えれば約2倍の処理能力になると思われるので大雑把にいってしまえば3つとも大体同じくらいの能力といえるかと思います。
以下に比較表にまとめました。
Raspberry Pi Pico | STM32F417 | Espressif ESP32 | |
製造・販売元 | Raspberry Pi | STマイクロ | Espressif |
CoreMark | 246.50(私による計測) | 565.73(CoreMark.org Scoresより) | 660.70(CoreMark.org Scoresより) |
CoreMark / MHz | 1.85 | 3.37 | 4.13 |
コア・アーキテクチャ | ARM Cortex-M0+ | ARM Cortex-M4 + FPU | Xtensa LX6 |
コア数 | 1 | 1 | 2 |
クロック周波数 | 133MHz |
168MHz |
160MHz |
マイコンボード価格 | @550 |
STM32F407G-DISCO @2,356(Digikey) Core的にはF417と同等 |
ESP32-WROVER-B @704(スイッチサイエンス) |
マイコン単価 |
RP2040 @118(Digikey) + W25Q16JVU(Flash 2MB) @58(Digikey) |
STM32F417VE @1,520(DigiKey) | モジュール(マイコンボード)でないと技適が通らないので、実質入手不可 |
比較検討 |
高CP |
ツール、開発ボード類が充実。使いやすい。 性能は落ちるがSTM32F0x系を用いれ低価格品あり |
Bluetooth、Wifiペリフェラル付き (アンテナ付き:技適あり) |
価格は2021年7月15日現在。
pico(RP2040)は高CP、ESP32は通信ペリフェラル付き、というところに優位性があります。
STマイクロ社製はPico、ESP32と比べると見劣りしているようですが、一般的には十二分な能力を持っているので簡単に使うには向いていると思います。
終わり