iPhone 3G = 4.8 GFlops?

by syoyo

genki さんと一緒に,
iPhone や iPod touch に載っている ARM プロセッサの VFP(ベクトル浮動小数点ユニット) について調べていました.

とりあえず現時点で理解したこと.

VFP は一度に演算するベクトル長を指定できる.

浮動小数点ステータスレジスタの LEN ビットにベクトル長を書き込むことで、
FP 命令 (fmuls など)はそのベクトル長ぶんの演算を一度に行うという、ちょっと変態なアーキになっている.
通常の FPU としての利用だと、ベクトル長 = 1 ということ.
ベクトル長は単精度だと最大 8 個、倍精度だと 4 個まで設定できる.

ただし、ベクトル長ぶんのレジスタバンク(レジスタペア)を消費する.
単精度だと全部で 32 レジスタ(s0 ~ s31)、倍精度だと 16 レジスタ(d0 ~ d16)あるけど、
たとえばベクトル長 4 なら、各命令のオペランドは [s8, s11] などという風に 4 個レジスタを消費する.
つまり、こんな感じの動作モデルになる.


# ベクトル長  = 1 の場合:
fmuls s8, s9, s10    ; s8 = s9 * s10

# ベクトル長 = 4 の場合:
fmuls s8, s12, s16  ; s8  = s12 * s16
                    ; s9  = s13 * s17
                    ; s10 = s14 * s18
                    ; s11 = s15 * s19

また、レジスタすべてをベクトル演算用に使うことはできなくて、
単精度の場合、s0 ~ s7 のレジスタバンクはスカラ演算のみに使うことができる.
つまり、単精度でベクトル長=4 のときだと、実質的には 6 SIMD レジスタ(4×6=24) しか扱えない.
倍精度に至っては、ベクトル長=4 だと 3 SIMD レジスタしか使えない.
パイプライン実行で命令レイテンシを隠してパフォーマンスを出すことを考えると、
6 レジスタでぎりぎりなんとかストールなしになるかも..、というところか.

VFP で SIMD 演算のプログラミング

通常の浮動小数点演算コードは、iPhone SDK の gcc-arm により、
ベクトル長=1 の条件で浮動小数点命令にマップされるけれども、
ベクトル長 = 4 などの SIMD 演算命令出力はサポートされていない.

llvm の ARM バックエンドも、 型の演算は、単純に 4 回の fp 演算に展開されてしまう.
また gcc で C 言語から VFP 命令を直接扱える intrinsic 関数のインターフェイスもない.
(VFP の後発の NEON だと, intrinsic 関数がある).

なので、現状 VFP で SIMD 演算をしたかったら、アセンブラでプログラミングするほかないようです.
ここはやはりオレコンパイラバックエンドを書ければ理想ですね.

VFP 演算ピークはいくら?

VFP には FMAC(積和命令) があり、レイテンシ/スループットは 1/8 である.
(タイミングは、ベクトル長には関係ないのかな?)

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344c/ch16s07s01.html

ベクトル長 = 4, 単精度のときを考える.
iPhone 3G だと 600 MHz くらいのクロックのようなので、 VFP もこの速度で動いているとすると、

0.6(GHz) x 2(FMAC) x 4(SIMD LEN) = 4.8 GFlops

となります.
仮説が正しければ、ポテンシャルとしては、
iPhone 3G は Core2 2GHz の 1/4 くらいの浮動小数点パフォーマンスがあることになります.

けっこう、iPhone でメガデモというのも可能性としてありそうかな?… 🙂

Advertisements