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 と浮動小数演算最適化