Ice Lake の PC (mac) を手に入れたので vfpbench を AVX512 対応にしてみました。結果は下記のとおりです。

AVX512 reg GFLOPS fop IPC
AVX512VL vmulps ymm 256bit 55.2 8 6.3
AVX512VL vaddps ymm 256bit 55.6 8 6.3
AVX512VL vfmaddps ymm 256bit 111.3 16 6.3
AVX512F vmulps zmm 512bit 53.7 16 3.1
AVX512F vaddps zmm 512bit 54.0 16 3.1
AVX512F vfmaddps zmm 512bit 108.0 32 3.1
AVX512F vfmadd+mulps zmm 512bit 81.0 24 3.1
AVX512F vfmadd+addps zmm 512bit 81.2 24 3.1

・Core i5-1030NG7 (MacBook Air)

AVX512 は、512bit 単位の演算が可能となる Intel の新しい SIMD 命令セットです。AVX/AVX2 は 256bit 幅なので 2倍に増えたことになります。単精度の浮動小数点演算なら 512/32bit = 16並列です。4x4 matrix が 1レジスタに収まります。

SSE から AVX に進化したときと同じように、命令のエンコードも一新されており機能も増えています。SSE → AVX では 3オペランドになり 64bit 時に 16個のレジスタが利用できました。AVX → AVX512 ではレジスタフィールドが 5bit となり、レジスタ数が 32個に増えています。さらに 7個の mask レジスタを併用することができます。

mask レジスタは初期の GPU の Shader にあった書き込みマスクと同じものです。出力レジスタのうち必要な要素のみ置き換えることができます。残りの部分は元の値が残りますが、保存せずにゼロクリアを行うこともできます。

mask レジスタが導入されたことで、大きくて一見小回りがきかないようにみえる 512bit のレジスタも、任意のベクタ長とみなして扱うことができます。単精度なら 16個分ですが、mask を併用すれば 1~15 個の単位でも読み書きができるわけです。

SSE/AVX では少々扱いづらかった x,y,z の 3要素ベクタも簡単にロードすることができます。 下記の例ではベクタ (x,y,z) を 4個まとめて読み込んでいます。長さ 12 のベクタとして読み込んだあと、それぞれ (x,y,z) → (x,y,z,0) に展開しています。

movl    $0x0fff, %eax
kmovw   %eax, %k1
movl    $0x7777, %eax
kmovw   %eax, %k2

movups     data(%rbp), %zmm0{%k1}{z}    ; mask 0xfff で読み込み
vexpandps  %zmm0, %zmm1{%k2}{z}         ; mask 0xfff -> 0x7777 に展開

AVX2 でも gather を使えば似たようなことができますが、どちらかといえば gather 命令は Shader の InputAssembler に相当します。

もちろん常時マスク付きで演算を行うと無駄が生じていることになります。GPU の SIMT のように、SoA で扱う方が AVX512 の本来の形かもしれません。この場合レジスタはベクタではなく 16個(単精度の場合)のスカラーとなり、mask レジスタは 16個のフラグレジスタとみなせます。

float d= n.dot( l );
if( d < 0 ){
    c+= a;
}else{
    c+= b * d;
}

例えば↑こんな感じのコードを 16並列で実行すると↓こうなります。

vmulps        %zmm8, %zmm11, %zmm20
vfmadd231ps   %zmm9, %zmm12, %zmm20
vfmadd231ps   %zmm10, %zmm13, %zmm20
vcmpps        $1, %zmm20, %zmm18, %k1
knotw         %k1, %k2
vfmadd231ps   %zmm20, %zmm19, %zmm21{%k1}
vaddps        %zmm17, %zmm21, %zmm21{%k2}

比較命令の結果であるフラグ値は mask レジスタに入るので、条件成立時と不成立時の演算結果をそのまま合成することができます。


AVX512 の説明が少々長くなりましたが、IceLake の vfpbench の結果を見てみます。ピークの GFLOPS 値は AVX(FMA3) 命令でも AVX512 命令でも変わっていないことがわかります。Ice Lake の場合 zmm (512bit) の AVX512F 命令は同時に 1命令しか実行できないようです。

AVX reg GFLOPS fop IPC
FMA3 vfmaddps ymm 256bit 111.0 16 6.3
AVX512VL vfmaddps ymm 256bit 111.3 16 6.3
AVX512F vfmaddps zmm 512bit 108.0 32 3.1

この結果は Intel のサイトでも確認できます。

Intel: Intrinsics Guide

上記ページの「__m512 _mm512_fmadd_ps (__m512 a, __m512 b, __m512 c)」を見ると、Icelake の throughput は 1 なので実行に 1 cycle かかることがわかります。対して Skylake (server)/Knights Landing の方は 0.5 なので、2 命令実行できることを意味しています。

また同じ AVX512 の命令でも、mask 付きの ymm(256bit) は AVX/FMA 同様 2命令実行できています。Intrinsics Guide で確認してみると throughput は 0.5 なので合っているようです。

よって IceLake の場合は、性能を上げるために無理に AVX512 命令を使う必要は無さそうです。ただし最初に紹介したように、AVX512 ではレジスタが倍増し便利な機能も命令も増えています。mask が使える便利な AVX2 として見ても十分使い物になるのではないでしょうか。

反面 CPU によって対応機能が細かく別れてしまうので、最適化と互換性の両立はますます難しくなりそうです。


なお vfpbench の log で IPC に大きな数値が出ているのは CPU のベースクロックを元にしているためです。今回使用した Core i5-1030NG7 はベースが 1.1GHz で Single Thread の Boost 時に 3.5GHz になります。そのため 3.5/1.1 の 3.18 がおよそ IPC=1 と思ってください。

より詳細なログは下記からどうぞ

Hyperでんち: VFP Benchmark Log 計測結果まとめ


関連エントリ
4倍速い Ryzen 9 3950X の UE4 コンパイル速度
Snapdragon 845 ARMv8.2A 半精度 fp16 演算命令を使ってみる / Deep Learning 命令
Snapdragon 835 と 845 のコンパイル時間の比較&浮動小数点演算能力
Snapdragon 845 の浮動小数点演算速度
ARM CPU の浮動小数点演算能力まとめ
HTC 10 Snapdragon 820 Kyro の浮動小数点演算能力
iPhone SE, Apple A9 の浮動小数点演算速度
ARM Cortex-A53 の浮動小数点演算速度とコンパイル時間の比較
iPod touch 6 の浮動小数点演算速度は Core 2 Duo ライン超え
iPad Air 2 (Apple A8X) の浮動小数点演算能力
ARM cpu vfp の種類と fp16 命令を使ってみる
Intel AVX その3 命令
Intel AVX その2 転送
Intel AVX


Snapdragon 845 の CPU は Qualcomm の Kryo 385 が使われています。big.LITTLE の 8 core (4+4) 非対称構成なので、ぞれぞれの CPU core 毎に測定してみました。下記はいずれも big.LITTLE 構成の CPU を使った SoC です。

Device Single thread Multi thread
SoC CPU Core big little big little Total
Snapdragon 845 Kryo3854+4 22.3 13.7 84.4 54.9 139.3 GFLOPS
Exynos 7420 A57+A534+4 16.8 11.8 55.5 47.1 102.6 GFLOPS
Rockchip RK3399 A72+A532+4 16.1 11.8 32.1 47.2 79.3 GFLOPS
Snapdragon 808 A57+A532+4 14.5 11.2 29.1 44.9 74.0 GFLOPS
Snapdragon 821 Kryo 2+2 18.7 12.6 37.4 25.3 62.7 GFLOPS

・big = big core, little = little core
・Total = Multi thread の合計

vfpbench の単精度の結果のみ抜き出しています。単位は GFLOPS 。数値が大きい方が高速です。

表の CPU は Kryo, Kryo 385 (A75), Cortex-A57 いずれも 64bit x2 pipe なので、ピーク性能の差は純粋に core 数と clock 数で決まっています。

同様に little core の Cortex-A53/A55 も 64bit x2 の FP pipe を持っているので、数値上はほぼクロック差だけの違いとなっています。32bit 時代の little core Cortex-A7 と比べると性能は大きく上がっています。

初代 Kryo は Qualcomm 独自 core ですが、Snapdragon 845 の Kyro 385 は ARM Cortex-A75 + A55 がベースになっているようです。そのため Snapdragon 845 Kryo 385 の特性は初代 Kryo は異なっています。

例えば Kyro と Kyo 385 は積和命令のピーク演算はどちらも同一ながら、加算だけなら Snapdragon 821 の Kryo の方が 2倍速く回っています。

下記の表は 1 cycle に実行できる命令数 (IPC)

Device 64bit 128bit
CPU Core mul/fma add mul/fma add
Kryo (Snapdragon 821) 2 4 1 2
Kryo 385 (A75/A55)/A72/A57/A53 2 2 1 1

Kryo 385 のもとになった Cortex-A75 は ARM の新しい命令セットに対応しています。

Kryo 385 (A75/A55) ARMv8.2-A
Cortex-A72/57/53 ARMv8.0-A

以前の fp16 (半精度浮動小数点) 対応は変換命令だけでした。ロードストアは fp16 でも演算は fp32 以上に変換してから行います。v8.2 対応の A75/A55 では Deep Learning 向けに 16bit 命令が強化されています。fp16 のまま直接演算できるようになりました。

ARM FPU (VFP/NEON) の種類

例えば NEON (Advanced SIMD) では 128bit 時に 8並列で演算が行われます。単精度 32bit と比べると 2倍の速度が出るはずなので、余裕があったら試してみたいと思います。


テストに使った機種の詳細

Pixel 3 Snapdragon 845 SDM845 4+4 Kryo 385 (A75/A55) 2.8GHz 1.8GHz
Galaxy S6 Exynos 7420 4+4 Cortex-A57/A53 2.1GHz 1.5GHz
C101PA Rockchip RK3399 2+4 Cortex-A72/A53 2.0GHz 1.5GHz
ZenfoneAR Snapdragon 821 MSM8996 2+2 Kryo 2.3GHz 2.1GHz
Nexus 5X Snapdragon 808 MSM8992 2+4 Cortex-A57/A53 1.8GHz 1.4GHz


関連エントリ
ARM CPU 上の開発環境とコンパイル時間の比較 (2) Pixel 3/UserLAnd
ARM CPU の浮動小数点演算能力まとめ
HTC 10 Snapdragon 820 Kyro の浮動小数点演算能力
HTC 10 Snapdragon 820 Kyro の浮動小数点演算能力
iPhone SE, Apple A9 の浮動小数点演算速度
Raspberry Pi 3 の速度比較, Cortex-A53 の速度
ARM Cortex-A53 の浮動小数点演算速度とコンパイル時間の比較
iPod touch 6 の浮動小数点演算速度は Core 2 Duo ライン超え
iPad Air 2 (Apple A8X) の浮動小数点演算能力


ARMv8A NEON flop
Apple Cyclone 128bit mla 2 16
Apple Typhoon 128bit mla 2 16
Apple Twister 128bit mla 3 24
NVIDIA Denver 128bit mla 1 + add 1 12
ARM Cortex-A53 64bit mla 2 8
ARM Cortex-A57 64bit mla 2 8
ARM Cortex-A72 64bit mla 2 8
Qualcomm Kyro 64bit mla 1 + add 1 6
ARMv7A NEON flop
ARM Cortex-A8 64bit mla 1 4
ARM Cortex-A9 32bit mac 1 2
ARM Cortex-A9 NEON 64bit mla 1 4
ARM Cortex-A7 32bit fma 1 2
ARM Cortex-A15 64bit fma 2 8
Qualcomm Scorpion 128bit mla 1 8
Qualcomm Krait 128bit fma 1 8
Apple Swift 128bit fma 1 8

暫定のまとめ。上の表は単精度のみです。vfpbench の結果から推定した値になります。
倍精度 (ARMv8A のみ) は下記のとおりです。

ARMv8A NEON flop-dp
Apple Cyclone 128bit mla 2 8
Apple Typhoon 128bit mla 2 8
Apple Twister 128bit mla 2 8
NVIDIA Denver 128bit mla 1 + add 1 6?
ARM Cortex-A53 64bit mla 2 4
ARM Cortex-A57 64bit mla 2 4
ARM Cortex-A72 64bit mla 2 4
Qualcomm Kyro 64bit mla 1 + add 1 3


関連ページ
CPU の浮動小数点演算能力の詳細
64bit ARMv8A CPU Core
VFP Benchmark Log 計測結果まとめ


|