FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

David Patterson教授の提唱しているベンチマークスイートEmbenchでコードサイズを比較する

少し興味があって各種アーキテクチャでのコードサイズの比較をやってみたくなり、良いベンチマークスイートが無いかを調べていたのだが、RISC-V Summit 2019でDavid Patterson教授の発表したEmbenchを試してみることにした。 Embenchはその名の通り組み込み向けに開発されているベンチマークスイートなので、Linux環境が無くても簡単にコンパイルできる、と期待している。

github.com

ダウンロードして中身を確認してみると、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で統一して、全体のテキストサイズを抽出した。比較したグラフがこちら。

f:id:msyksphinz:20200608235701p:plain
EmBenchを各アーキテクチャコンパイルした結果のコードサイズ

全体的にRV64GCは優秀だが、ARMv8の方がコードサイズが小さい。特にcubicベンチマークで格段の違いが出てきている。この差はどうもlong doubleをABIがサポートするかどうかの違いらしい。

github.com

ABIがサポートしないCubicを抜いて全体のコードサイズを確認するとRV64GCの方が優れている。やはり実際にコードを確認してみると面白い。