SlideShare una empresa de Scribd logo
1 de 17
Descargar para leer sin conexión
x64 のスカラー,SIMD 演算性能を
測ってみた
C++ MIX #10
2024/4/19
2024/4/21 改版
@suzumushi0
鈴木 宗良
改版履歴
 2024/4/19 初版
 2024/4/21はぇ~@haxe さまのご指摘を受けて以下を追記修正
 x64 数値演算の拡張命令の AVX-512 に半精度浮動小数点を追加
valarray の性能問題の推定原因,積和演算命令への変換,floatの逆数命令への変換を追記修正
2
背 景
 DAW (Digital Audio Workstation: 楽曲作成ソフト) 向けのエフェクタープラグインを開発
• 立体音響用プラグイン等のバイナリ,ソースを無償で公開
• DAW はディジタル信号処理の実験プラットフォームとして最適
 プラグイン信号処理部の実体はリアルタイムの数値計算
• 処理時間に上限
• CPU 負荷は最大 1%−数% 程度
 構想段階で,実現可能性をどう判断する?
• 作ってみなければ判らない,出たとこ勝負ではリスクが高い
• 経験値から感覚論で判断?
• 感覚論であっても CPU の演算性能に関する基本的なデータが必要
3
評価の目的と適用性
 評価の目的
• Visual C++ による x64 スカラー,ベクトル数値演算命令のスループットを評価
• 演算命令の直接記述やアセンブリ言語は使用しない
 評価の適用性
• スループットはループ処理による繰り返し演算やベクトル演算の性能指標
• 単発の演算ではレイテンシが重要な性能指標となるが,今回は評価しない
• スループット性能は,繰り返し回数やベクトルの次数による影響を強く受ける
• コンパイラによって変換された機械語ルーチンの構造はこれらに依存
• Visual C++ の Vup,他のコンパイラ,他の CPU,GPU では全く異なる結果となる可能性は十分にある
4
x64 数値演算の拡張命令
拡張命令 機能概要 VC++ オプション
SSE2 128 bit 長 16 本の XMM レジスタ による浮動小数点のスカラー,ベクトル演算 (SIMD),整数のベクトル演算
32 bit 単精度浮動小数点の四則,平方根,逆数,平方根の逆数演算命令
64 bit 倍精度浮動小数点の四則,平方根演算命令
8, 16, 32, 64 bit 整数の加算,減算命令,16, 32 bit 整数の乗算命令
default
AVX2 256 bit 長 16 本の YMM レジスタによる浮動小数点のスカラー,ベクトル演算 (SIMD),整数のベクトル演算
3-4 オペランドの新命令形式によるレジスタ割り当ての効率化
32 bit 単精度浮動小数点の四則,平方根,逆数,平方根の逆数,積和演算命令
64 bit 倍精度浮動小数点の四則,平方根,積和演算命令
8, 16, 32, 64 bit 整数の加算,減算命令,16, 32 bit 整数の乗算命令
/arch:AVX2
AVX-512 512 bit 長 32 本 の ZMM レジスタ による浮動小数点のスカラー,ベクトル演算 (SIMD),整数のベクトル演算
16 bit 半精度浮動小数点の四則,平方根,積和,複素積,複素積和演算命令
32 bit 単精度浮動小数点の四則,平方根,逆数,平方根の逆数,積和演算命令
64 bit 倍精度浮動小数点の四則,平方根,積和演算命令
8, 16, 32, 64 bit 整数の加算,減算命令,16, 32, 64 bit 整数の乗算命令
/arch:AVX512
AMX 512 bit 長ベクトル演算レジスタによる 8 bit 整数,16 bit 半精度浮動小数点行列の積演算
行列の最大サイズは 1K Byte,整数で 16 行 64 列,浮動小数点で 16 行 32 列
演算結果は 32 bit 整数か 32 bit 単精度浮動小数点行列
未サポート
5
Note: Visual C++ オプションは最低要件を示す (機能制限では無い).デフォルトの SSE2 では,SSE4.1 や AVX-512 の命令 (pmulld, vpmullq) と,
スカラー演算命令の双方に変換され,実行時に cpuid に基づいて選択される.
Visual C++ におけるベクトル演算
 Visual C++ コンパイラの自動ベクトル化機能
• ループ処理における最適化機能の一つ
• x64 ベクトル演算命令へ変換される場合がある
 C++ 標準ライブラリの valarray
• 明示的にベクトル演算を記述
• x64 ベクトル演算命令へ変換される場合がある
 Visual C++ 独自機能の組み込み (intrinsics) 関数
• x64 ベクトル演算命令を直接記述
• 今回は対象としない
6
ループ処理の最適化
 演算性能はコンパイラによる最適化に強く依存
 Visual C++ の最適化 /O2 は以下を含む
ループ展開 (Loop unrolling)
• for 文,while 文による演算のループを,スカラー演算命令を羅列したループに変換
• Visual C++ でループ展開される条件は不明
 自動ベクトル化 (Automatic vectorization)
• for 文,while 文による演算のループを,ベクトル演算命令を羅列したループに変換
• Visual C++ で自動ベクトル化される条件は不明確
• 自動ベクトル化レポート出力オプション
[構成プロパティ]>[C/C++]>[コマンドライン]>[追加のオプション] に /Qvec-report:2 を追加
• 自動ベクトル化の抑止
ループ記述の前に #pragma loop (no_vector) を挿入
7
ループ展開の例
 5 回ループ展開された加算命令の例
 2, 4, 5, 10 回のループ展開を確認
8
$LL43@main:
; 108 : for (int j = 0; j < len; j++)
; 109 : *c32_p++ = *a32_p++ + *b32_p++;
mov eax, DWORD PTR [r10]
lea r10, QWORD PTR [rcx+20] r10 update
add eax, DWORD PTR [r9] スカラー加算
lea r9, QWORD PTR [rdx+20] r9 update
mov DWORD PTR [r11], eax
lea r11, QWORD PTR [r8+20] r11 update
mov eax, DWORD PTR [rcx+4]
add eax, DWORD PTR [rdx+4] スカラー加算
mov DWORD PTR [r8+4], eax
mov eax, DWORD PTR [rdx+8]
add eax, DWORD PTR [rcx+8] スカラー加算
mov DWORD PTR [r8+8], eax
mov eax, DWORD PTR [rcx+12]
add eax, DWORD PTR [rdx+12] スカラー加算
mov DWORD PTR [r8+12], eax
mov eax, DWORD PTR [rdx+16]
mov rdx, r9 rdx update
add eax, DWORD PTR [rcx+16] スカラー加算
mov rcx, r10 rcx update
mov DWORD PTR [r8+16], eax
mov r8, r11 r8 update
sub rbx, 1 loop カウンタ更新
jne SHORT $LL43@main
エラーメッセージから推定した
自動ベクトル化の条件
対象は for 文, while 文によるループ (do 文は対象外)
for (int i; i < 1000; i++)
ループ変数はローカル変数のみ; ループ終了条件はループ開始時から不変; ループ変数更新は +1 のみ
{
NG: 依存関係のあるループ計算
NG: if, switch, break, continue 文等の条件分岐
OK: 浮動小数点の四則演算,sqrt (),整数の加減乗算,math 関数 (演算速度は不変),inline 関数
NG: その他の関数
NG: bit 長が異なる変数への代入
NG: 32, 64bit 以外の構造体メンバへの参照
NG: 連続しない配列要素の参照
NG: 可変回数のシフト演算
} 等々謎
9
評価方法
 評価環境
• Core i7 8565U 1.8GHz (8th Gen.)
• Visual C++ v143
 評価対象
• int16 (short), int32 (int), int64 (long long), float, double の四則,平方根演算
• ループ展開無し,有りにおけるスカラー演算
• 自動ベクトル化,valarray によるベクトル演算 (SSE2, AVX2)
 評価指標
• 各演算を 1,000M 回繰り返し,経過時間を計測
• 1 回あたりの平均演算時間を CPU クロック数に換算し,スループットとする
10
スカラー演算のスループット
11
add sub mul div add sub mul div
ループ展開なし ループ展開
int16 1.15 1.16 1.28 4.25 0.48 0.47 0.58 3.22
int32 1.18 1.18 1.18 4.21 0.47 0.46 0.47 3.00
int64 1.18 1.17 1.18 12.19 0.48 0.69 0.48 10.99
float 1.15 1.15 1.15 1.23 0.53 0.51 0.53 1.23
double 1.19 1.16 1.17 1.70 0.51 0.52 0.51 1.69
0.00
0.50
1.00
1.50
2.00
2.50
3.00
3.50
4.00
4.50
5.00
int16 int32 int64 float double
12.19 10.99
Throughput
[clocks]
整数ベクトル演算のスループット
12
add sub mul add sub mul add sub mul add sub mul add sub mul
[参考] ループ展開 自動ベクトル化 SSE2 自動ベクトル化 AVX2 valarray SSE2 valarray AVX2
int16 0.48 0.47 0.58 0.08 0.07 0.10 0.07 0.06 0.07 0.28 0.21 0.20 0.20 0.19 0.19
int32 0.47 0.46 0.47 0.15 0.14 0.19 0.10 0.09 0.09 0.35 0.35 0.35 0.30 0.29 0.30
int64 0.48 0.69 0.48 0.29 0.27 0.28 0.24 1.03 1.00 1.58 1.59
0.00
0.10
0.20
0.30
0.40
0.50
0.60
0.70
0.80
int16 int32 int64
Throughput
[clocks]
1.03
1.00
1.58
1.59
valarray の int64 のスループットは非実用的
浮動小数点ベクトル演算の
スループット
13
add sub mul div sqrt add sub mul div sqrt add sub mul div sqrt add sub mul div sqrt add sub mul div sqrt
[参考] ループ展開 自動ベクトル化 SSE2 自動ベクトル化 AVX2 valarray SSE2 valarray AVX2
float 0.53 0.51 0.53 1.23 1.23 0.18 0.18 0.18 0.31 0.31 0.18 0.18 0.17 0.27 0.31 0.37 0.34 0.35 0.48 0.49 0.32 0.28 0.28 0.45 0.51
double 0.51 0.52 0.51 1.69 2.52 0.28 0.27 0.28 0.81 1.22 0.20 0.20 0.19 0.82 1.23 1.73 1.74 1.71 2.20 2.63 0.86 0.87 0.87 1.47 1.90
0.00
0.50
1.00
1.50
2.00
2.50
3.00
float double
Throughput
[clocks]
valarray の double のスループットは非実用的
[参考] 初等関数のスループット
14
exp (x) log (x) sin (x) cos (x) tan (x) asin (x) acos (x) atan (x) pow (x, y) pow (x, 2.0)
float 6.91 7.87 11.79 12.26 12.55 13.05 17.41 9.85 62.12 24.12
double 8.53 9.74 12.83 12.87 17.69 17.68 18.14 15.34 76.21 50.29
0.00
10.00
20.00
30.00
40.00
50.00
60.00
70.00
80.00
float double
Throughput
[clocks]
結 果
 スカラー演算のスループット
 加減乗算のスループットは語長に係わらず整数,浮動小数点で有意差は無い
 除算のスループットは,浮動小数点の方が高い
 ループ展開と比較した,整数ベクトル演算のスループット (自動ベクトル化)
 SSE2 の int32 は,加減算で約 3 倍,乗算で約 2 倍に性能向上
 AVX2 の int32 は 4 −5 倍に性能向上
ループ展開と比較した,浮動小数点ベクトル演算のスループット (自動ベクトル化)
 SSE2 の float は,加減乗算で約 3 倍,除算平方根で約 4 倍に性能向上
 SSE2 の double は約 2 倍の性能向上
 AVX2 の double は,加減乗算で約 3 倍の性能向上 (float と同等)
 その他
 valarray は int64, double の演算性能に問題あり,また自動ベクトル化より性能が低い
 int16 のスカラー乗算,除算は 32bit 命令に変換されている
 コンパイラは float の 逆数,平方根の逆数演算命令,AVX2 の積和演算命令への変換はしない
15
2024/4/21 追記
valarray の性能問題は,四則演算
結果を一時変数に記憶し,= で変数
に代入しているためと推定される
AVX2 の積和演算命令は
/fp:contract か /fp:fast を指定すれ
ば変換される
AVX-512 で追加された float の逆数
命令 (VRCP14PS) への変換はされる
おわりに
 スループットをどう使う?
• 例えば,サンプリングレートが 48KHz のデータを,クロック速度が 1.8GHz の CPU でリアルタイム処理
• CPU 負荷を 1% 以下とすると 1 サンプル処理のクロック数の上限は 1.8GHz / 48KHz / 100 = 375 clocks
• 次数 67 の FIR フィルタは積和演算が 67 回となるから 67 clocks 程度必要か
• 5 フィルタは行けるな,という感覚論
 x64 ベクトル演算は,使える局面を選ぶが,性能向上に確実に寄与する
• Visual C++ はループ展開や自動ベクトル化の条件をドキュメント化して欲しい
 valarray はベクトル演算を簡潔に記述できる利点がある
• Visual C++ は valarray の性能を,自動ベクトル化と比較して遜色ないレベルにして欲しい
 今回のスループット評価のソースコード
16
参考資料
 Intel CPU 技術資料
 Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined
Volumes: 1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D, and 4.
 Intel® 64 and IA-32 Architectures Optimization Reference Manual Volume 1.
 x86, x84 CPU 命令セット一覧
 x86, x64 CPU 命令のレイテンシ,スループット一覧
 CPU の拡張機能サポート状況表示ツール Coreinfo
17

Más contenido relacionado

Similar a x64 のスカラー,SIMD 演算性能を測ってみた v0.1 @ C++ MIX #10

Wavelet matrix implementation
Wavelet matrix implementationWavelet matrix implementation
Wavelet matrix implementation
MITSUNARI Shigeo
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
Takeshi Yamamuro
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
MITSUNARI Shigeo
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011final
Mikio Kubo
 

Similar a x64 のスカラー,SIMD 演算性能を測ってみた v0.1 @ C++ MIX #10 (20)

Wavelet matrix implementation
Wavelet matrix implementationWavelet matrix implementation
Wavelet matrix implementation
 
Gurobi python
Gurobi pythonGurobi python
Gurobi python
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920 10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920
 
10分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 110110分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 1101
 
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenIntel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
 
optimal Ate pairing
optimal Ate pairingoptimal Ate pairing
optimal Ate pairing
 
「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」
「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」
「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
 
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
 
OpenCVの拡張ユーティリティ関数群
OpenCVの拡張ユーティリティ関数群OpenCVの拡張ユーティリティ関数群
OpenCVの拡張ユーティリティ関数群
 
20190625 OpenACC 講習会 第3部
20190625 OpenACC 講習会 第3部20190625 OpenACC 講習会 第3部
20190625 OpenACC 講習会 第3部
 
llvm入門
llvm入門llvm入門
llvm入門
 
Slide
SlideSlide
Slide
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011final
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 

x64 のスカラー,SIMD 演算性能を測ってみた v0.1 @ C++ MIX #10

  • 1. x64 のスカラー,SIMD 演算性能を 測ってみた C++ MIX #10 2024/4/19 2024/4/21 改版 @suzumushi0 鈴木 宗良
  • 2. 改版履歴  2024/4/19 初版  2024/4/21はぇ~@haxe さまのご指摘を受けて以下を追記修正  x64 数値演算の拡張命令の AVX-512 に半精度浮動小数点を追加 valarray の性能問題の推定原因,積和演算命令への変換,floatの逆数命令への変換を追記修正 2
  • 3. 背 景  DAW (Digital Audio Workstation: 楽曲作成ソフト) 向けのエフェクタープラグインを開発 • 立体音響用プラグイン等のバイナリ,ソースを無償で公開 • DAW はディジタル信号処理の実験プラットフォームとして最適  プラグイン信号処理部の実体はリアルタイムの数値計算 • 処理時間に上限 • CPU 負荷は最大 1%−数% 程度  構想段階で,実現可能性をどう判断する? • 作ってみなければ判らない,出たとこ勝負ではリスクが高い • 経験値から感覚論で判断? • 感覚論であっても CPU の演算性能に関する基本的なデータが必要 3
  • 4. 評価の目的と適用性  評価の目的 • Visual C++ による x64 スカラー,ベクトル数値演算命令のスループットを評価 • 演算命令の直接記述やアセンブリ言語は使用しない  評価の適用性 • スループットはループ処理による繰り返し演算やベクトル演算の性能指標 • 単発の演算ではレイテンシが重要な性能指標となるが,今回は評価しない • スループット性能は,繰り返し回数やベクトルの次数による影響を強く受ける • コンパイラによって変換された機械語ルーチンの構造はこれらに依存 • Visual C++ の Vup,他のコンパイラ,他の CPU,GPU では全く異なる結果となる可能性は十分にある 4
  • 5. x64 数値演算の拡張命令 拡張命令 機能概要 VC++ オプション SSE2 128 bit 長 16 本の XMM レジスタ による浮動小数点のスカラー,ベクトル演算 (SIMD),整数のベクトル演算 32 bit 単精度浮動小数点の四則,平方根,逆数,平方根の逆数演算命令 64 bit 倍精度浮動小数点の四則,平方根演算命令 8, 16, 32, 64 bit 整数の加算,減算命令,16, 32 bit 整数の乗算命令 default AVX2 256 bit 長 16 本の YMM レジスタによる浮動小数点のスカラー,ベクトル演算 (SIMD),整数のベクトル演算 3-4 オペランドの新命令形式によるレジスタ割り当ての効率化 32 bit 単精度浮動小数点の四則,平方根,逆数,平方根の逆数,積和演算命令 64 bit 倍精度浮動小数点の四則,平方根,積和演算命令 8, 16, 32, 64 bit 整数の加算,減算命令,16, 32 bit 整数の乗算命令 /arch:AVX2 AVX-512 512 bit 長 32 本 の ZMM レジスタ による浮動小数点のスカラー,ベクトル演算 (SIMD),整数のベクトル演算 16 bit 半精度浮動小数点の四則,平方根,積和,複素積,複素積和演算命令 32 bit 単精度浮動小数点の四則,平方根,逆数,平方根の逆数,積和演算命令 64 bit 倍精度浮動小数点の四則,平方根,積和演算命令 8, 16, 32, 64 bit 整数の加算,減算命令,16, 32, 64 bit 整数の乗算命令 /arch:AVX512 AMX 512 bit 長ベクトル演算レジスタによる 8 bit 整数,16 bit 半精度浮動小数点行列の積演算 行列の最大サイズは 1K Byte,整数で 16 行 64 列,浮動小数点で 16 行 32 列 演算結果は 32 bit 整数か 32 bit 単精度浮動小数点行列 未サポート 5 Note: Visual C++ オプションは最低要件を示す (機能制限では無い).デフォルトの SSE2 では,SSE4.1 や AVX-512 の命令 (pmulld, vpmullq) と, スカラー演算命令の双方に変換され,実行時に cpuid に基づいて選択される.
  • 6. Visual C++ におけるベクトル演算  Visual C++ コンパイラの自動ベクトル化機能 • ループ処理における最適化機能の一つ • x64 ベクトル演算命令へ変換される場合がある  C++ 標準ライブラリの valarray • 明示的にベクトル演算を記述 • x64 ベクトル演算命令へ変換される場合がある  Visual C++ 独自機能の組み込み (intrinsics) 関数 • x64 ベクトル演算命令を直接記述 • 今回は対象としない 6
  • 7. ループ処理の最適化  演算性能はコンパイラによる最適化に強く依存  Visual C++ の最適化 /O2 は以下を含む ループ展開 (Loop unrolling) • for 文,while 文による演算のループを,スカラー演算命令を羅列したループに変換 • Visual C++ でループ展開される条件は不明  自動ベクトル化 (Automatic vectorization) • for 文,while 文による演算のループを,ベクトル演算命令を羅列したループに変換 • Visual C++ で自動ベクトル化される条件は不明確 • 自動ベクトル化レポート出力オプション [構成プロパティ]>[C/C++]>[コマンドライン]>[追加のオプション] に /Qvec-report:2 を追加 • 自動ベクトル化の抑止 ループ記述の前に #pragma loop (no_vector) を挿入 7
  • 8. ループ展開の例  5 回ループ展開された加算命令の例  2, 4, 5, 10 回のループ展開を確認 8 $LL43@main: ; 108 : for (int j = 0; j < len; j++) ; 109 : *c32_p++ = *a32_p++ + *b32_p++; mov eax, DWORD PTR [r10] lea r10, QWORD PTR [rcx+20] r10 update add eax, DWORD PTR [r9] スカラー加算 lea r9, QWORD PTR [rdx+20] r9 update mov DWORD PTR [r11], eax lea r11, QWORD PTR [r8+20] r11 update mov eax, DWORD PTR [rcx+4] add eax, DWORD PTR [rdx+4] スカラー加算 mov DWORD PTR [r8+4], eax mov eax, DWORD PTR [rdx+8] add eax, DWORD PTR [rcx+8] スカラー加算 mov DWORD PTR [r8+8], eax mov eax, DWORD PTR [rcx+12] add eax, DWORD PTR [rdx+12] スカラー加算 mov DWORD PTR [r8+12], eax mov eax, DWORD PTR [rdx+16] mov rdx, r9 rdx update add eax, DWORD PTR [rcx+16] スカラー加算 mov rcx, r10 rcx update mov DWORD PTR [r8+16], eax mov r8, r11 r8 update sub rbx, 1 loop カウンタ更新 jne SHORT $LL43@main
  • 9. エラーメッセージから推定した 自動ベクトル化の条件 対象は for 文, while 文によるループ (do 文は対象外) for (int i; i < 1000; i++) ループ変数はローカル変数のみ; ループ終了条件はループ開始時から不変; ループ変数更新は +1 のみ { NG: 依存関係のあるループ計算 NG: if, switch, break, continue 文等の条件分岐 OK: 浮動小数点の四則演算,sqrt (),整数の加減乗算,math 関数 (演算速度は不変),inline 関数 NG: その他の関数 NG: bit 長が異なる変数への代入 NG: 32, 64bit 以外の構造体メンバへの参照 NG: 連続しない配列要素の参照 NG: 可変回数のシフト演算 } 等々謎 9
  • 10. 評価方法  評価環境 • Core i7 8565U 1.8GHz (8th Gen.) • Visual C++ v143  評価対象 • int16 (short), int32 (int), int64 (long long), float, double の四則,平方根演算 • ループ展開無し,有りにおけるスカラー演算 • 自動ベクトル化,valarray によるベクトル演算 (SSE2, AVX2)  評価指標 • 各演算を 1,000M 回繰り返し,経過時間を計測 • 1 回あたりの平均演算時間を CPU クロック数に換算し,スループットとする 10
  • 11. スカラー演算のスループット 11 add sub mul div add sub mul div ループ展開なし ループ展開 int16 1.15 1.16 1.28 4.25 0.48 0.47 0.58 3.22 int32 1.18 1.18 1.18 4.21 0.47 0.46 0.47 3.00 int64 1.18 1.17 1.18 12.19 0.48 0.69 0.48 10.99 float 1.15 1.15 1.15 1.23 0.53 0.51 0.53 1.23 double 1.19 1.16 1.17 1.70 0.51 0.52 0.51 1.69 0.00 0.50 1.00 1.50 2.00 2.50 3.00 3.50 4.00 4.50 5.00 int16 int32 int64 float double 12.19 10.99 Throughput [clocks]
  • 12. 整数ベクトル演算のスループット 12 add sub mul add sub mul add sub mul add sub mul add sub mul [参考] ループ展開 自動ベクトル化 SSE2 自動ベクトル化 AVX2 valarray SSE2 valarray AVX2 int16 0.48 0.47 0.58 0.08 0.07 0.10 0.07 0.06 0.07 0.28 0.21 0.20 0.20 0.19 0.19 int32 0.47 0.46 0.47 0.15 0.14 0.19 0.10 0.09 0.09 0.35 0.35 0.35 0.30 0.29 0.30 int64 0.48 0.69 0.48 0.29 0.27 0.28 0.24 1.03 1.00 1.58 1.59 0.00 0.10 0.20 0.30 0.40 0.50 0.60 0.70 0.80 int16 int32 int64 Throughput [clocks] 1.03 1.00 1.58 1.59 valarray の int64 のスループットは非実用的
  • 13. 浮動小数点ベクトル演算の スループット 13 add sub mul div sqrt add sub mul div sqrt add sub mul div sqrt add sub mul div sqrt add sub mul div sqrt [参考] ループ展開 自動ベクトル化 SSE2 自動ベクトル化 AVX2 valarray SSE2 valarray AVX2 float 0.53 0.51 0.53 1.23 1.23 0.18 0.18 0.18 0.31 0.31 0.18 0.18 0.17 0.27 0.31 0.37 0.34 0.35 0.48 0.49 0.32 0.28 0.28 0.45 0.51 double 0.51 0.52 0.51 1.69 2.52 0.28 0.27 0.28 0.81 1.22 0.20 0.20 0.19 0.82 1.23 1.73 1.74 1.71 2.20 2.63 0.86 0.87 0.87 1.47 1.90 0.00 0.50 1.00 1.50 2.00 2.50 3.00 float double Throughput [clocks] valarray の double のスループットは非実用的
  • 14. [参考] 初等関数のスループット 14 exp (x) log (x) sin (x) cos (x) tan (x) asin (x) acos (x) atan (x) pow (x, y) pow (x, 2.0) float 6.91 7.87 11.79 12.26 12.55 13.05 17.41 9.85 62.12 24.12 double 8.53 9.74 12.83 12.87 17.69 17.68 18.14 15.34 76.21 50.29 0.00 10.00 20.00 30.00 40.00 50.00 60.00 70.00 80.00 float double Throughput [clocks]
  • 15. 結 果  スカラー演算のスループット  加減乗算のスループットは語長に係わらず整数,浮動小数点で有意差は無い  除算のスループットは,浮動小数点の方が高い  ループ展開と比較した,整数ベクトル演算のスループット (自動ベクトル化)  SSE2 の int32 は,加減算で約 3 倍,乗算で約 2 倍に性能向上  AVX2 の int32 は 4 −5 倍に性能向上 ループ展開と比較した,浮動小数点ベクトル演算のスループット (自動ベクトル化)  SSE2 の float は,加減乗算で約 3 倍,除算平方根で約 4 倍に性能向上  SSE2 の double は約 2 倍の性能向上  AVX2 の double は,加減乗算で約 3 倍の性能向上 (float と同等)  その他  valarray は int64, double の演算性能に問題あり,また自動ベクトル化より性能が低い  int16 のスカラー乗算,除算は 32bit 命令に変換されている  コンパイラは float の 逆数,平方根の逆数演算命令,AVX2 の積和演算命令への変換はしない 15 2024/4/21 追記 valarray の性能問題は,四則演算 結果を一時変数に記憶し,= で変数 に代入しているためと推定される AVX2 の積和演算命令は /fp:contract か /fp:fast を指定すれ ば変換される AVX-512 で追加された float の逆数 命令 (VRCP14PS) への変換はされる
  • 16. おわりに  スループットをどう使う? • 例えば,サンプリングレートが 48KHz のデータを,クロック速度が 1.8GHz の CPU でリアルタイム処理 • CPU 負荷を 1% 以下とすると 1 サンプル処理のクロック数の上限は 1.8GHz / 48KHz / 100 = 375 clocks • 次数 67 の FIR フィルタは積和演算が 67 回となるから 67 clocks 程度必要か • 5 フィルタは行けるな,という感覚論  x64 ベクトル演算は,使える局面を選ぶが,性能向上に確実に寄与する • Visual C++ はループ展開や自動ベクトル化の条件をドキュメント化して欲しい  valarray はベクトル演算を簡潔に記述できる利点がある • Visual C++ は valarray の性能を,自動ベクトル化と比較して遜色ないレベルにして欲しい  今回のスループット評価のソースコード 16
  • 17. 参考資料  Intel CPU 技術資料  Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D, and 4.  Intel® 64 and IA-32 Architectures Optimization Reference Manual Volume 1.  x86, x84 CPU 命令セット一覧  x86, x64 CPU 命令のレイテンシ,スループット一覧  CPU の拡張機能サポート状況表示ツール Coreinfo 17