※ 이 글은 오가사와라 히로유키(小笠原博之) 씨가 블로그에 적은 글을 번역한 것입니다. 사정에 따라 예고없이 삭제될 수 있으므로 양해부탁드립니다.
Nexus 9 NVIDIA Tegra K1 64 Denver의 부동소수점 연산속도
(원문 : Nexus 9 NVIDIA Tegra K1 64 Denver の浮動小数点演算速度)
VFP Benchmark의 Android판도 64bit에 대응시켰습니다. 대응되면 arm64(arm64-v8a), x86_64(x64), mips64로 계측합니다. 또한 iOS판은 이미 64bit(arm64)에 대응되어 있습니다.
아래는 Nexus 9 (Tegra K1 64)에서의 결과 비교입니다.
NVIDIA Denver ST-SP ST-DP MT-SP MT-DP
----------------------------------------------------------------
AArch32 32bit armv7a 17.799 4.423 34.582 8.719 GFLOPS
AArch64 64bit arm64 17.906 8.762 34.888 17.601 GFLOPS
* ST=Single thread, MT=Multi thread
* SP=Single precision fp, DP=Double precision fp
* 단위는 GFLOPS, 수치가 높을수록 고속
AArch64는 배정밀도 NEON 명령을 사용할 수 있기에 DP의 속도가 2배가 됩니다. 보다 자세한 결과는 아래 페이지에 올려놨습니다.
// Tegra K1 Denver arm64
시간(sec) MFLOPS
---------------------------------------------------
FPU fmul (32bit x1) n8 : 2.049 1952.1
FPU fadd (32bit x1) n8 : 1.000 3998.3
FPU fmadd (32bit x1) n8 : 1.849 4326.0
NEON fmul.2s (32bit x2) n8 : 1.842 4343.8
NEON fadd.2s (32bit x2) n8 : 1.259 6356.0
NEON fmla.2s (32bit x2) n8 : 1.900 8420.3
NEON fmul.4s (32bit x4) n8 : 1.837 8711.7
NEON fadd.4s (32bit x4) n8 : 1.179 13570.5
NEON fmla.4s (32bit x4) n8 : 1.831 17475.0
FPU fmul (64bit x1) n8 : 1.930 2072.7
FPU fadd (64bit x1) n8 : 0.929 4306.0
FPU fmadd (64bit x1) n8 : 1.798 4450.2
NEON fmul.2d (64bit x2) n8 : 1.809 4422.6
NEON fadd.2d (64bit x2) n8 : 1.195 6695.8
NEON fmla.2d (64bit x2) n8 : 1.826 8762.0
fmul.2s, fmul.4s의 속도차이가 없는 것으로 보아, Cortex-A15과 달리 NEON 명령이 128bit 단위로 실행되는 것이라 생각됩니다. 아마도 Nexus 9의 Denver는 2.2GHz 전후로 동작하고, 1 cycle 당 스칼라 곱셈이 1, 덧셈이 2. SIMD에서는 이 비율이 4 mul, 6 add, 4 mad입니다. 표로 정리하면 아래와 같습니다. (수치가 클수록 cycle 당 연산능력이 높음)
Scalar SP Scalar DP
mul add mad mul add mad
----------------------------------------------
Cortex-A9 32 1 1 2 0.5 1 1
Cortex-A15 32 1 1 2 1 1 1.4
Krait 400 32 1 1 2 1 1 2 (Qualcomm)
Swift 32 1 1 1 1 1 1 (Apple A6)
Denver 64 1 2 2 1 2 2 (NVIDIA Tegra) ←
Cyclone 64 2 3 4 2 3 4 (Apple A7/A8)
Silvermont 64 1 1 - 0.5 1 - (Intel BayTrail Atom)
Jaguar 64 1 1 2 0.5 1 - (AMD Kabini)
SIMD2(32x2) SP SIMD4(32x4) SP SIMD2(64x2) DP
mul add mad mul add mad mul add mad
------------------------------------------------------------------
Cortex-A9 32 2 2 4 2 2 4 - - -
Cortex-A15 32 4 4 8 4 4 8 - - -
Krait 400 32 2 2 4 4 4 8 - - -
Swift 32 2 2 4 4 4 8 - - -
Denver 64 2 3 4 4 6 8 2 3 4 ←
Cyclone 64 4 6 8 8 12 16 4 6 8
Silvermont 64 - - - 2 4 6 0.5 1 1.5
Jaguar 64 - - - 4 4 8 2 2 4
↑이 표는 명령당 연산개수로, 덧곱셈을 2로 처리했습니다. 더 자세한 표는 아래 페이지에 올려놓았습니다.
Denver는 CPU core와 비교해도 비교적 얌전한 결과를 보입니다. 부동소수점 연산에 있어서도 딱히 돌출된 특징이 없어, core의 수가 적은만큼 Multi-Thread 시의 최대치가 낮습니다. 아래 표는 32bit 버전 Tegra K1을 탑재한 SHIELD Tablet과의 비교입니다.
Tegra K1 (수치는 GFLOPS) ST-SP ST-DP MT-SP MT-DP
---------------------------------------------------------------
Denver AArch32 32bit armv7a 17.799 4.423 34.582 8.719 Nexus 9
Denver AArch64 64bit arm64 17.906 8.762 34.888 17.601 Nexus 9
Cortex-A15 ARMv7A 32bit armv7a 17.136 3.431 70.174 14.036 SHIELD Tab
이것만 보면 Cortex-A15 버전쪽이 나은 것처럼 보이지만, 어디까지나 부동소수점 연산명령만 본 결과입니다. 실제로는 ARM의 64bit 명령셋을 쓸 수 있다는 큰 메리트가 있어, 응용 프로그램의 동작속도에는 이렇다할 큰 차이가 나지 않을거라 생각됩니다.
↓표는 WebGL (Emscripten) 물리 엔진 벤치마크의 결과비교로, Nexus 9은 상당히 고속으로 실행되고 있습니다.
Nexus 9 Tegra K1 Denver 64 Android 5.0 Firefox 33 13개
iPad Air 2 Apple A8X Cyclone 64 iOS 8.1 Safari 13개
MeMO Pad ME176 Z3740 Silvermont 32 Android 4.4 Firefox 33 9개
Tegra Note 7 Tegra 4 Cortex-A15 32 Android 4.4 Firefox 33 8개
Nexus 5 MSM8974 Krait 400 32 Android 4.4 Firefox 33 8개
Nexus 7 APQ8064 Krait 32 Android 5.0 Firefox 33 5개
자세한 것은 아래 페이지에서. 현재는 Firefox에서도 제대로 표시되게 되었습니다.
Android NDK의 어셈블러 명령
clang과 gcc4.9의 차이일지도 모르지만, 왼쪽의 생략표기를 쓸 수 없기에 오른쪽과 같이 레지스터 명으로 전개하는 것이 필요합니다.
orr.16b v1, v0, v0 → orr v1.16b, v0.16b, v0.16b
fmla.4s v0, v8, v4 → fmla v0.4s, v8.4s, v4.4s
관련글