Qualcomm APQ8064 Krait/A6 swift の浮動小数点演算能力

Qualcomm の CPU Krait の浮動小数点演算の速度を調べてみました。

                 (1)     (2)     (3)      (4)    (5)
                 iPad3  Touch5   EVO 3D  iPad4 Butterfly
                 A5X     A5      8660     A6X    8064
                 C-A9    C-A9   Scorpion Swift   Krait
--------------------------------------------------------
a:mat44 neon_AQ  4.784   5.979   2.879   1.204   1.919
b:mat44 neon_BQ  2.408   3.008   1.146   1.266   1.273
c:mat44 neon_AD  4.781   5.974   3.079   1.554   2.453
d:mat44 neon_BD  2.406   3.007   1.440   1.344   2.041
e:fadds      A   4.010   5.013   3.460   2.882   3.791
f:fmuls      A   4.010   5.012   4.361   2.953   3.671
g:fmacs      A   4.012   5.011   4.034   5.763   7.334
h:vfma.f32   A   -----   -----   -----   5.765   3.725
i:vadd.f32 D A   4.111   5.136   3.493   2.877   3.706
j:vmul.f32 D A   4.110   5.136   3.502   2.950   3.667
k:vmla.f32 D A   4.512   5.650   3.638   2.951   7.557
l:vadd.f32 Q A   8.023  10.036   3.408   2.878   3.677
m:vmul.f32 Q A   8.022  10.028   3.427   2.952   3.647
n:vmla.f32 Q A   8.025  10.028   3.400   2.955   7.362
o:vfma.f32 D A   -----   -----   -----   2.494   3.676
p:fadds      B   4.014   5.013   5.972   5.757   4.664
q:fmuls      B   5.013   6.265   5.960   5.760   4.583
r:fmacs      B   8.023  10.024   8.573  11.521   8.266
s:vfma.f32   B   -----   -----   -----  11.519   4.611
t:vadd.f32 D B   4.113   5.137   5.945   2.881   4.746
u:vmul.f32 D B   4.118   5.145   5.098   2.951   4.680
v:vmla.f32 D B   9.027  11.278   8.498   5.757   8.361
w:vadd.f32 Q B   8.021  10.023   5.950   2.879   4.702
x:vmul.f32 Q B   8.029  10.023   5.095   2.951   4.595
y:vmla.f32 Q B   9.026  11.277   8.497   5.762   8.464
z:vfma.f32 D B   -----   -----   -----   5.759   4.660
--------------------------------------------------------
↑数値は実行時間(秒) 数値が小さい方が速い


(1)=Apple iPad 3           A5X      ARM Cortex-A9 x2  1.0GHz
(2)=Apple iPod touch 5     A5       ARM Cortex-A9 x2  0.8GHz
(3)=HTC EVO 3D ISW12HT     MSM8660  Scorpion      x2  1.2GHz
(4)=Apple iPad 4           A6X      A6 (swift)    x2    ?GHz
(5)=HTC J butterfly HTL21  APQ8064  Krait         x4  1.5GHz

(1)~(4) は過去の計測値です。
SDK や OS などの条件が完全に同一ではないのと、計測方法にも
いろいろミスや勘違いが含まれてる可能性があります。
予めご了承ください。

またアプリケーションの実速度ではなく CPU 単体の能力やパイプラインを
調べるのが目的なので、オンキャッシュ前提で意味のない演算を走らせています。

● a:~d: NEON を使った Matrix 4×4 同士の乗算

A はパイプライン最適化なし、B はインターリーブしたものです。
Q=128bit(float x4), D=64bit(float x2) 命令です。
64bit の方が実行命令数が倍になります。
具体的な違いは下記の通り。

; AQ
    vldmia	%0, {d0-d7}
    vldmia	%1, {d8-d15}
    vmul.f32	q8,q0,d8[0]
    vmla.f32	q8,q1,d8[1]
    vmla.f32	q8,q2,d9[0]
    vmla.f32	q8,q3,d9[1]
    vstmia	%2!, {d16,d17}
    ~

; BQ
    vldmia	%0, {d0-d7}
    vldmia	%1, {d8-d15}
    vmul.f32	q8,q0,d8[0]
    vmul.f32	q9,q0,d10[0]
    vmul.f32	q10,q0,d12[0]
    vmul.f32	q11,q0,d14[0]
    ~

; BD
    vldmia	%0, {d0-d7}
    vldmia	%1, {d8-d15}
    vmul.f32	d16,d0,d8[0]
    vmul.f32	d17,d1,d8[0]
    vmla.f32	d16,d2,d8[1]
    vmla.f32	d17,d3,d8[1]
    vmla.f32	d16,d4,d9[0]
    vmla.f32	d17,d5,d9[0]
    vmla.f32	d16,d6,d9[1]
    vmla.f32	d17,d7,d9[1]
    vstmia	%2!, {d16,d17}
    ~

● e:~z: VFP/NEON の命令単体の実行

vfma は VFPv4 の新しい命令なので、CPU A6(Swift), Krait のみ
実行できます。(Cortex-A9/Scorpion は VFPv3)

無印 = VFP スカラー (float x1)
D    = NEON d レジスタ 64bit (float x2)
Q    = NEON q レジスタ 128bit (float x4)

A は in/out が完全に別レジスタです。
B は 4 命令毎のインターリブで、レイテンシが大きい場合は
A よりもストールする可能性が高くなります。

// A
#define NEON_OPSETv1_8D(op)	\
	op " d0, d1, d1 \n"	\
	op " d2, d1, d1 \n"	\
	op " d3, d1, d1 \n"	\
	op " d4, d1, d1 \n"	\
	op " d5, d1, d1 \n"	\
	op " d6, d1, d1 \n"	\
	op " d7, d1, d1 \n"	\
	op " d8, d1, d1 \n"

// B
#define NEON_OPSETv2_8D(op)	\
	op " d0, d1, d5 \n"	\
	op " d2, d1, d6 \n"	\
	op " d3, d1, d7 \n"	\
	op " d4, d1, d8 \n"	\
	op " d5, d1, d0 \n"	\
	op " d6, d1, d2 \n"	\
	op " d7, d1, d3 \n"	\
	op " d8, d1, d4 \n"

● ALU

(1)/(2) Cortex-A9 の NEON は 64bit (float x2) なので
j: と m: のように D , Q で倍近い差が生じています。

(3) Qualcomm は Scorpion でも NEON が 128bit なので、
j: と m: の差がなく Q では Cortex-A9 の倍の速度が出ています。

(4)/(5) Scorpion 同様 D,Q の差がほとんど無く、NEON が 128bit
だと考えられます。

● Pipeline

(3) の Scorpion は 128bit NEON かつクロックが高いこともあり、
(1)/(2) の Cortex-A9 と比べると全体的に fp 性能が高くなっています。

ですが e:~o: の A に比べて p:~z: の落ち込みが起きており、
低クロックの Cortex-A9 より遅くなっているケースがあります。
Cortex-A9 の場合一部の命令以外は A と B の差が生じていません。

Scorpion は pipeline のステージが深いこと、Cortex-A9 も積和の
fmacs/vmla ではレイテンシが大きいことがわかります。

(4) の A6(Swift) は NEON の場合 A/B の差がほとんど無く、
全体的にスループットが高くなっています。
NEON も out of order で実行していると考えられます。

ただし VFP のスカラーの方が B で遅くなっているため、
レジスタリネーミングは 64bit 単位ではないかと思います。
特にスカラーの積和命令が極端に苦手です。

おそらく fmacs/vmla/vfma の sレジスタアクセスは d 全体を
置き換えるベクタ命令に置き換えた方が高速化できると思われます。

(5) の Krait は Scorpion と比べて明らかにパイプラインの実行効率が
高くなっています。
A/B の差は小さくなっており A6(swift) 同様 out-of-order か latency が
少ないと考えられます。特に a:~d: で差が顕著です。
それでも A6 には敵いません。

特徴的なのは vmla が遅いことで、VFP v4 の vfma と大きな開きがあります。
HW Native なのは vfma の方で、vmla は演算結果の互換性のために mul,add
2命令に展開している可能性があります。
よって、Krait ではできる限り vfma を使った方が良いことになります。

● Krait

Scorpion は浮動小数点演算能力が非常に高いのですが、
ピーク性能を引き出すのはあまり容易ではありませんでした。
その点 Krait は改良されているようです。

ただし整数演算やアプリケーション全体の実行速度ではまだ
大きな差を検出できていません。
Android NDK r8c/r8d では clang (LLVM) が追加されているので、
コンパイラを変えるとまた違った結果になる可能性があります。

また Scorpion にはなかった Quad core なので、システム全体の
速度では最も演算能力が高いことは間違いありません。
同じ Quad core でも Tegra3 などの Cortex-A9 とは世代が異なっており
特に浮動小数点演算能力は 2倍になります。

前回書いたように APQ8064 の Adreno 320 GPU の方もかなり速いのですが、
ベンチマークに使用しているアプリが安定して動作せず計測できていません。
まだ安定しない原因がわかっておりません。

関連エントリ
Adreno 320 Snapdragon S4 Pro APQ8064
iPhone 5 / A6 の CPU 速度 その 3
iPhone 5 / A6 の浮動小数点演算
Snapdragon の本当の浮動小数点演算能力
ARM Cortex-A8 の NEON と浮動小数演算最適化