少し興味があって各種アーキテクチャでのコードサイズの比較をやってみたくなり、良いベンチマークスイートが無いかを調べていたのだが、RISC-V Summit 2019でDavid Patterson教授の発表したEmbenchを試してみることにした。 Embenchはその名の通り組み込み向けに開発されているベンチマークスイートなので、Linux環境が無くても簡単にコンパイルできる、と期待している。
ダウンロードして中身を確認してみると、MakefileではなくPythonの環境を用いてコンパイルするらしい。大丈夫かなあ。。。
./build_all.py --clean --arch=arm --chip=cortex-m4 --board=generic
File "./build_all.py", line 145 log.error(f'ERROR: Architecture "{args.arch}" not found: exiting') ^ SyntaxError: invalid syntax
いきなりコケた。どうもGitHub Issuesを確認していると、Python 3.6以降のバージョンが必要らしい。なんでそんなに厳しいバージョンが必要なんだ。。。
./build_all.py --clean --arch=native --chip=size-test-gcc --board=default
nativeでのコンパイルはx86でのコンパイルとなる。まあ私がx86マシンを使用しているから。コンパイルが終了するとbd
ディレクトリにバイナリが生成される。
これをすべて解析してテキストサイズ領域を抽出してみることにした。
for f in `find -executable -type f` do objdump -d ${f} > ${f}.dmp && readelf -a ${f} | grep FUNC > ${f}.func && size ${f} > ${f}.size done
RISC-Vでのコンパイルを試行する。以下のオプションでビルド実行してみたが、いきなり失敗する。っていうか何でデフォルトで失敗するようになっているのだ。 仕方がないのでRV64GCでコンパイルするように変更した。
diff --git a/config/riscv32/chips/generic/chip.cfg b/config/riscv32/chips/generic/chip.cfg index 6632c3e..1c30655 100644 --- a/config/riscv32/chips/generic/chip.cfg +++ b/config/riscv32/chips/generic/chip.cfg @@ -67,4 +67,12 @@ # - we garbage collect unused sections on linking -cc = 'riscv32-unknown-elf-gcc' +cc = 'riscv64-unknown-linux-gnu-gcc' + +cflags = [ + '-c', '-march=rv64gc', '-Os', '-fdata-sections', '-ffunction-sections' +] +ldflags = [ + '-Os', '-Wl,-gc-sections' +] +user_libs = ['-lm']
ARM v8でのコンパイルは以下のようになった。これもやはりコンフィグレーションを書き換えの必要があった。いろいろ面倒くさい。
diff --git a/config/arm/chips/cortex-m4/chip.cfg b/config/arm/chips/cortex-m4/chip.cfg index e9cdedd..dd493e1 100644 --- a/config/arm/chips/cortex-m4/chip.cfg +++ b/config/arm/chips/cortex-m4/chip.cfg @@ -17,4 +17,11 @@ # - each global data and function is put in its own section # - we garbage collect unused sections on linking -cc = 'arm-none-eabi-gcc' +cc = 'arm-linux-gnueabihf-gcc' +cflags = [ + '-march=armv8.4-a', '-c', '-Os', '-fdata-sections', '-ffunction-sections' +] +ldflags = [ + '-Os', '-Wl,-gc-sections' +] +user_libs = ['-lm', '-lc']
全てのコンパイルオプションを-Os
で統一して、全体のテキストサイズを抽出した。比較したグラフがこちら。
全体的にRV64GCは優秀だが、ARMv8の方がコードサイズが小さい。特にcubic
ベンチマークで格段の違いが出てきている。この差はどうもlong double
をABIがサポートするかどうかの違いらしい。
ABIがサポートしないCubicを抜いて全体のコードサイズを確認するとRV64GCの方が優れている。やはり実際にコードを確認してみると面白い。