浮動小数点演算機能をISSに実装するにあたり、どのような検証方法、ベンチマークの測定方法があるのかを調査してみよう。
整数系のベンチマークプログラムには、有名なDhrystone、Coremarkがあるが、これらのベンチマークには浮動小数点が入っていない。 Dhrystoneと似ている名前だが、Whetstoneというベンチマークを発見した。
Whetstone ベンチマークは浮動小数点演算性能を主に計測する。整数演算や文字列演算向けの同様のベンチマークとして Dhrystone がある。
いいですね。まずは、ソースコードをダウンロードする。
Benchmark Programs and Reports
http://www.netlib.org/benchmark/whetstone.c
中身を見てみると、確かに大量の浮動小数点演算が入っている。三角関数や、対数関数も入っていた。
/* map the FORTRAN math functions, etc. to the C versions */ #define DSIN sin #define DCOS cos #define DATAN atan #define DLOG log #define DEXP exp #define DSQRT sqrt
殆どの演算が、倍精度で計算するように実装されているようだ。まあ、型を一括で変換すればそこは単精度にも簡単に変換できるかな。
WhetstoneベンチマークをMIPSアーキテクチャ向けにコンパイルしてみる
まずは、Whetstone.cでコンパイルできるかな。
mips-img-elf-gcc -c -O3 whetstone.c
あとは、タイマー機能、printfなどは不要なので、その辺りも全てカットしていく。
#ifdef X86_SIMULATION #include <time.h> #endif // X86_SIMULATION ... #ifdef X86_SIMULATION II = 1; /* start at the first arg (temp use of II here) */ while (II < argc) { if (strncmp(argv[II], "-c", 2) == 0 || argv[II][0] == 'c') { continuous = 1; } else if (atol(argv[II]) > 0) { loopstart = atol(argv[II]); } else { fprintf(stderr, USAGE); return(1); } II++; } #endif // X86_SIMULATION ... #ifdef X86_SIMULATION startsec = time(0); #endif // X86_SIMULATION
これでコンパイルできたので、スタートアップコードと、リンカスクリプト、システムコール用関数を追加して、コンパイルしてみる。
mips-img-elf-gcc -O3 -g -mips64r6 whetstone.c startup.s syscalls.c -Tlinker.ld -lm -lg -o whetstone
ダンプしてみると、大量の浮動小数点演算が入っているのが分かった。まずはこれをターゲットとして、ISSを作っていこう。
mips-img-elf-objdump -D whetstone
大量の浮動小数点命令が追加されている。
80009630 <main>: 80009630: d7810018 ldc1 $f1,24(gp) 80009634: 27bdfff0 addiu sp,sp,-16 80009638: d7800048 ldc1 $f0,72(gp) 8000963c: 3c027f00 lui v0,0x7f00 80009640: d7820040 ldc1 $f2,64(gp) 80009644: 24424988 addiu v0,v0,18824 80009648: d7880030 ldc1 $f8,48(gp) 8000964c: 24032ee0 li v1,12000 80009650: d7830020 ldc1 $f3,32(gp) 80009654: 462009c6 mov.d $f7,$f1 80009658: f7804120 sdc1 $f0,16672(gp) 8000965c: 46200986 mov.d $f6,$f1 80009660: ffbf0008 sd ra,8(sp) 80009664: 46200906 mov.d $f4,$f1 80009668: ffb00000 sd s0,0(sp) 8000966c: 46200806 mov.d $f0,$f1 80009670: f7824110 sdc1 $f2,16656(gp) 80009674: f7884100 sdc1 $f8,16640(gp) 80009678 <.L2>: 80009678: 462018c0 add.d $f3,$f3,$f0 8000967c: 2463ffff addiu v1,v1,-1 80009680: 462418c0 add.d $f3,$f3,$f4 80009684: 462618c1 sub.d $f3,$f3,$f6 80009688: 462218c2 mul.d $f3,$f3,$f2 8000968c: 46211840 add.d $f1,$f3,$f1 80009690: 46270801 sub.d $f0,$f1,$f7 80009694: 46260000 add.d $f0,$f0,$f6 80009698: 46220002 mul.d $f0,$f0,$f2 8000969c: 46201941 sub.d $f5,$f3,$f0 800096a0: 462301c1 sub.d $f7,$f0,$f3 800096a4: 46200046 mov.d $f1,$f0 800096a8: 46242900 add.d $f4,$f5,$f4 800096ac: 46262100 add.d $f4,$f4,$f6 800096b0: 46222102 mul.d $f4,$f4,$f2 800096b4: 46272140 add.d $f5,$f4,$f7 800096b8: 462021c6 mov.d $f7,$f4 800096bc: 46262980 add.d $f6,$f5,$f6 800096c0: 1460ffed bnez v1,80009678 <.L2> 800096c4: 46223182 mul.d $f6,$f6,$f2 800096c8: d7850050 ldc1 $f5,80(gp) 800096cc: 240336b0 li v1,14000