SlideShare une entreprise Scribd logo
1  sur  29
Télécharger pour lire hors ligne
AVX-512(フォーマット)詳解
x86/x64最適化勉強会8 2018/2/17
光成滋生
• AVX-512の新機能概要
• AVX-512のフォーマット
概要
2 / 29
• 32個の512 bit SIMDレジスタ
• zmm0, zmm1, ..., zmm31
• 一つのSIMDレジスタには整数や小数が複数入る
• double(64bit) x 8, qword(64bit) x 8, float(32bit) x 16
• dword(32bit) x 16, word(16bit) x 32, byte(8bit) x 64など
• 一部の整数は符号あり・符号無しを選択可能
• 下位256bitは従来のymmレジスタとしてアクセス可能
• その下位128bitは従来のxmmレジスタとしてアクセス可能
AVX-512
zmm0
ymm0
xmm0
63 31 15 0
3 / 29
• 整数系 ; vp<演算><要素の型> dst, src1, src2
• d(dword x 32)として要素ごとにzmm2 = zmm1 + zmm0
• q(qword x 16)として要素ごとにzmm2 = zmm1 – zmm0
• 浮動小数点数系 ; v<演算><要素の型> dst, src1, src2
• pd(double x 16)として要素ごとにzmm2 = zmm1 * zmm0
• ps(float x 32)として要素ごとにzmm2 = zmm1 / zmm0
基本演算の例
vpaddd zmm2, zmm1, zmm0
vpsubq zmm2, zmm1, zmm0
vmulpd zmm2, zmm1, zmm0
vdivps zmm2, zmm1, zmm0
4 / 29
• AVX512F(foundation)
• blend, pcmp, ptest, compress等
• CD(Conflict Detection)
• 競合検出 ループ処理での補助
• ER(Exponential and Reciprocal)
• 指数と逆数
• PF(prefetch)
• プリフェッチ
• BW(byte, word), DQ(dword, qword)
• VL(Vector length)
• xmm, ymmレジスタ利用可能
演算グループ(1/2)
5 / 29
• VBMI(Vector byte Manipulation Instructions)
• pcompress, pexpand, pshld, vpermi2bなど
• IFMA(Integer Fused Multiply Add)
• 52bit整数の積の上位/下位52bitを加算
• 4FMAPS
(Fused Multiply Accumulation Packed Single Precision)
• 16個のfloat[]の積和演算4個を1命令で
• 4VNNIW(Vector Neural Network Instructions Word
variable precision)
• 4個のword[]の積和(結果はdword)16個を1命令で
• GFNI(Galois Field系)
• 標数2の8次拡大体の元のアフィン変換/逆変換を1命令で
演算グループ(2/2)
6 / 29
• 共通
• BAIC = AVX512{F, CD}
• 主に浮動小数点数強化系
• Knights Landing = BASIC + AVX512{ER, PF}
• Knights Mill = Knights Landing + AVX512_{4FMAPS, 4VNNIW}
• 主に整数強化系
• Skylake = BASIC + AVX512{BW, DQ, VL}
• Cannon Lake = Skylake + AVX512_{VBMI, IFMA}
• Ice Lake = Cannon Lake + AVX512_{VBMI2, VNNI, GFNI, ... }
対応CPU
7 / 29
• SIMDは特定の要素の例外処理が面倒
• AVX2までのやり方
• vcmppdで要素ごとに(a[i] > 1.0) ? (-1) : 0のマスクMを生成
• M &= a[i] ; 要素ごとにa[i] or 0
• M *= b[i] ; 要素ごとにa[i] * b[i] or 0
• vblendvpd命令で要素ごとにa[i] * b[i]かb[i]を選択
SIMDの苦手なこと
double *a, *b, *c;
for (int i = 0; i < n; i++) {
double x = b[i];
if (a[i] > 1.0) x *= a[i];
c[i] = x;
}
8 / 29
• 要素ごとにマスク設定が可能になった
• 64bitマスクレジスタk1, ..., k7
• k0もあるがマスク設定には使えない
• 要素数だけマスクレジスタの下位bitが参照される
• 8byte x 64なら64bit, 32byte x 16なら16bit
• マスクレジスタの扱い
• 該当bitが1 ; 該当要素の処理が行われる
• 該当bitが0
• ゼロ化マスクなし
• 操作は行われない(例外や違反は発生しない)
• ゼロ化マスクあり
• 0で埋められる
AVX-512におけるマスク処理
9 / 29
• vmovdqu8(byte単位のレジスタコピー)
• k1レジスタのビットが立っているところだけコピー
マスクの例
[Xf Xe Xd Xc Xb Xa X9 X8 X7 X6 X5 X4 X3 X2 X1 X0]xmm0
[Yf Ye Yd Yc Yb Ya Y9 Y8 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0]xmm1
[ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0]k1
[Yf Ye Yd Yc Yb Ya Y9 Y8 Y7 Y6 Y5 X4 Y3 Y2 X1 Y0]xmm1
vmovdqu8 xmm1{k1}, xmm0
10 / 29
• vmovdqu8(byte単位のレジスタコピー)
• k1レジスタのビットが立っているところだけコピー
• それ以外は0クリア
ゼロ化マスクの例
[Xf Xe Xd Xc Xb Xa X9 X8 X7 X6 X5 X4 X3 X2 X1 X0]xmm0
[Yf Ye Yd Yc Yb Ya Y9 Y8 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0]xmm1
[ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0]k1
[00 00 00 00 00 00 00 00 00 00 00 X4 00 00 X1 00]xmm1
vmovdqu8 xmm1{k1}{z}, xmm0
11 / 29
• 再掲
• AVX-512のマスクレジスタを利用
先程のサンプルの例
double *a, *b, *c;
for (int i = 0; i < n; i++) {
double x = b[i];
if (a[i] > 1.0) x *= a[i];
c[i] = x;
}
// zmm2 = [1.0 ... 1.0]を設定しておく
vmovups zmm0, [a] ; double x 16読み
vmovups zmm1, [b]
vcmppd k1, zmm2, zmm0, 1 ; k1=[(zmm2 < zmm0) ? 1 : 0]
vmulpd zmm1{k1}, zmm0, zmm1 ; a[i] > 1のところだけ乗算
vmovups [c], zmm1
12 / 29
• マスクのコスト
• ロードでブレンド操作が行われるため少し低速
• デスティネーション(以下dstと略記)との依存関係が発生
• ゼロ化マスクではこの依存関係は切れる
• 可能な限りゼロ化マスクを使う
• メモリへの書き込みはマージmaskのみ
• 書き込みアドレスが書き込み禁止領域にまたがっていても
マスクレジスタでマスクされていると例外は発生しない
マスクレジスタの注意点
+0 +1 +2 +3 +4 +5 +6 +7 +8|+9 +a +b +c +d +e +f
[yy yy yy yy yy yy yy yy yy|xx xx xx xx xx xx xx]
書き込み禁止領域書き込み可能領域
k1 = (1 << 9) – 1のとき
13 / 29
• 複数の条件のandやorを効率よく計算するために
マスクレジスタの演算命令が追加されている
• k<演算>{b,w,d,q} dst, src1, src2の形
• add, and, or, not, xor
• andn(x, y) := ~(x & y)
• xnor(x, y) := ~(x ^ y)
• shiftl, shiftrなど
• ZF, CF制御系
• kortest{b,w,d,q} src1, src2
• (src1 | src2) == 0ならZF = 1
• (src1 | src2) == ~0ならCF = 1
• vcomiss x, yよりvcomiss k, x, y; kortest k, kの方が速いらしい
マスクレジスタの演算
14 / 29
• マスクレジスタが立っているところだけ集める
データ圧縮
[Xf Xe Xd Xc Xb Xa X9 X8 X7 X6 X5 X4 X3 X2 X1 X0]xmm0
[ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0]k1
[00 00 00 00 00 00 00 00 00 00 00 00 00 00 X4 X1]xmm1
vcompresspd xmm1{k1}, xmm0
15 / 29
• a[]が正のところだけb[]につめていく
データ圧縮の例
assert(n % 16 == 0);
uint32_t a[n];
uint32_t b[n];
j = 0;
for (int i = 0; i < n; i++) {
if (a[i] > 0) {
b[j++] = a[i];
}
}
16 / 29
• メイン部分
AVX-512によるデータ圧縮
// rsi = a, rdi = b, zmm0 = rax = rdx = 0
.lp:
vmovdqa32 zmm1, [rsi + rax * 4] ; zmm1 = a[]
vpcmpgtd k1, zmm1, zmm0 ; k1 = [(a > 0)?1:0]
vpcompressd zmm2{k1}, zmm1 ; zmm2 = comp(a[])
vmovdqu32 [rdi + rdx * 4], zmm2 ; b[] = zmm2
kmovd ecx, k1
popcnt rcx, rcx ; コピーした個数だけ
add rdx, rcx ; bのポインタを増やす
add rax, 16 ; aは16ずつ増やす
cmp rax, n
jne .lp
17 / 29
• マスクレジスタが立っているところに下から入れる
データ展開
[Xf Xe Xd Xc Xb Xa X9 X8 X7 X6 X5 X4 X3 X2 X1 X0]xmm0
[ 0 0 0 1 0 0 0 0 0 1 0 1 0 0 1 0]k1
[00 00 00 X3 00 00 00 00 00 X2 00 X1 00 00 X0 00]xmm1
vcompresspd xmm1{k1}{z}, xmm0
18 / 29
• 32 or 64bitの値をSIMDレジスタに複数個コピー
• 従来
• AVX-512
• 外に{1to8}, {1to4}など
• レジスタ種別(xmm/ymm/zmm)と
データの型(float/double)で{1toX}のXは一意に決まる
• Xbyakではptr_b[rax]と書けるようにした
ブロードキャストフラグ
vbroadcastss zmm0, [rax] ; [rax]のfloat1個を16個コピー
vmulps zmm2, zmm1, zmm0
vmulps zmm2, zmm1, [rax]{1to16}
19 / 29
• 従来
• 浮動小数点数の演算結果の丸め方はMXCSRレジスタに依存
• MXCSRの変更はコストが大きい
• round系は小数→小数のみ, cvtt系は小数→整数の切り捨てのみ
• AVX-512
• ほとんどの命令毎に丸め方を指定可能
• rne(round to nearest even) ; 最も近い偶数
• rd(round down) ; 切り下げ
• ru(round up) ; 切り上げ
• rz(round toward zero) ; ゼロへの丸め
• 同時に例外抑制SAE(suppress all exceptions)も行われる
組み込み丸め操作
vcvtsd2si eax,xmm0,{rz-sae} ;小数→整数のゼロへの丸め
20 / 29
• 1bitが3個の入力x, y, zに対して1bitのwを出力する関数f
• f(x, y, z) = w ; fは8bit定数imm8を一つ決めると決まる
• vpternlog x, y, z, imm8 ; x = f(x, y, z)
imm8=e8h
• 例)SHA関数の中のf(a, b, c) = ((a | b) & c) | (a & b)や
f(a, b, c) = a ^ (b ^ (c ^ a))はvpternlog1命令にできる
3値論理(ternary logic)
x y z w
0 0 0 0
0 0 1 0
0 1 0 0
0 1 1 1
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 1
21 / 29
• ModR/M
• mov dst, src / mov dst, [src] / mov dst, [src + disp]
などの1byteエンコーディング規則
• mod
• 00 ; dst, [src]
• 01 ; dst, [src + disp8](8bitオフセット)
• 10 ; dst, [src + disp32](32bitオフセット)
• 11 ; dst, src
• reg
• 8種類のレジスタを3bitで指定
• r/m
• srcのレジスタを指定
IA-32のフォーマット復習(1/2)
[ 7 6| 5 4 3| 2 1 0]
[ mod | reg | r/m ]
22 / 29
• SIB(Scale Index Byte)
• mov eax, [ecx + edx * 4 + disp]などのエンコーディング規則
• [base + index * scale + disp]
• base
• レジスタ種別
• index
• レジスタ種別
• scale
• 1, 2, 4, 8倍をそれぞれ00, 01, 10, 11で表現
IA-32のフォーマット復習(2/2)
[ 7 6| 5 4 3| 2 1 0]
[scale| index | base ]
23 / 29
• modR/M + SIB
• ~32bit, レジスタ8個
• REXプレフィクス(1byte)
• inc/dec reg16を廃止して利用
• 64bit, レジスタ16個対応
• VEXプレフィクス(2-3byte, Vector Extension)
• les, ldsの隙間を利用
• 3オペランド, 256bitレジスタ対応
• デコーダの負担を低減
• EVEXプレフィクス(4byte, Enhanced VEX)
• 64bitモードで廃止されていたbound(0x62)始まり
• 512bit, レジスタ32個対応
• マスクレジスタ、丸めモード、ブロードキャストなど
エンコーディングの歴史
24 / 29
• テスト
• mmとppは従来のVEXプレフィクス関係
• zはゼロ化フラグ, L’Lはレジスタ長や丸めモード
EVEX
| EVEX |
|62 P0 P1 P2| opcode ModRM/M [SIB] [Disp] [Imm]
| 7 6 5 4 3 2 1 0 |
P0 | R | X | B | R'| 0 | 0 | m | m |
P1 | W | v | v | v | v | 1 | p | p |
P2 | z | L'| L | b | V'| a | a | a |
vaddpd a4a3a2a1a0,{k_aaa},b4b3b2b1b0,c4c3c2c1c0
| P0 | P1 | P2 |
62|!a3 !c4 !c3 !a4 0001|1 b3 b2 b1 b0 101|0100 !b4 aaa|
| ModRM/M |
<opcode> |11 a2 a1 a0 c2 c1 c0| [SIB] [Disp]
25 / 29
• メモリアクセスのディスプレースメント(disp)は
符号つき8bit以内なら1byte, それ以外は4byte必要
• AVX-512ではzmm1個で64byteなので2個分のオフセッ
ト(128)でオーバーする
• これはデコーダに辛い
• 通常ループアンロールなどで使うのは0x40, 0x80, 0xc0など
64byteの倍数のはず
• オフセットがN(=64など)の倍数なら圧縮disp8を使う変更
圧縮disp8*N(1/2)
mov rax, [rax + 0x7f] ; 48 8B 40 7F ; disp8
mov rax, [rax + 0x80] ; 48 8B 80 80 00 00 00 ; disp32
vaddpd zmm0, zmm1, [rax] ;62F1F5485800 6byte
vaddpd zmm0, zmm1, [rax+0x80];62F1F548588080000000 10byte
26 / 29
• 命令長が7byteに収まる
• その代わり[rax+1]などはdisp8でなくdisp32で表現
• 余談
• 命令毎にdisp8*NのNの値のパターンが異なる
• Tuple TypeはInputSizeにより変わるのでややこしい
圧縮disp8*N(2/2)
vaddpd zmm0, zmm1, [rax+64] ; 62F1F548584001
vaddpd zmm0, zmm1, [rax+128]; 62F1F548584002
vaddpd zmm0, zmm1, [rax+192]; 62F1F548584003
vaddpd zmm0, zmm1, [rax+256]; 62F1F548584004
vaddpd zmm0, zmm1, [rax+1] ; 62F1F548588001000000
27 / 29
• v4fmaddps zmm1, zmm<base>, [mem]
• zmm<base>, ..., zmm<base+3>とfloat mem[4]の積和を
zmm1に加算(baseは4の倍数)
• zmm4を指定すればzmm4, zmm5, zmm6, zmm7が参照される
• 擬似コード
• デコーダの負担を減らすため?
v4fmaddps(Knights Mill以降)
v4fmaddps(zmm dest, zmm[base], float mem[4]) {
floatX16 tmp = dest;
for (j = 0; j < 4; j++) {
for (i = 0; i < 16; i++) {
tmp[i] += zmm[base + j][i] * msrc[j];
}
dest = tmp;
} }
28 / 29
• Intelのマニュアル&エミュレータ(SDE)
• https://software.intel.com/en-us/articles/intel-sdm
• https://software.intel.com/en-us/articles/intel-software-
development-emulator
• software developer‘s manual(325383-065US)の間違い
• p.1312のVSQRTPD xmm1 {k1}{z}, xmm2/m128/m32bcst
などはm64bcstの間違い
• Optimization Reference Manual(248966-039)の間違い
• p.540のvmovaps zmm1{k1}{z}, zmm0の結果の図がおかしい
• p.552の図15.5 Data Expand Operationがおかしい
• @tanakmuraさんのAVX-512 Advent Calendar 2014
• https://qiita.com/advent-calendar/2014/avx512
参考文献
29 / 29

Contenu connexe

Tendances

冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safeKumazaki Hiroki
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例Fixstars Corporation
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなKentaro Matsui
 
研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法Takeshi Yamamuro
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門Fixstars Corporation
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpsonickun
 
x86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTtakesako
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門Fixstars Corporation
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarrayRyosuke839
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織Takafumi ONAKA
 
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるAtsushi KOMIYA
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理Norishige Fukushima
 
C/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールC/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールMITSUNARI Shigeo
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxpsMITSUNARI Shigeo
 
基礎線形代数講座
基礎線形代数講座基礎線形代数講座
基礎線形代数講座SEGADevTech
 
競プロは社会の役に立たない+ベンチャー企業の話 (NPCA夏合宿OB講演).pdf
競プロは社会の役に立たない+ベンチャー企業の話 (NPCA夏合宿OB講演).pdf競プロは社会の役に立たない+ベンチャー企業の話 (NPCA夏合宿OB講演).pdf
競プロは社会の役に立たない+ベンチャー企業の話 (NPCA夏合宿OB講演).pdfcatupper
 

Tendances (20)

冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
Java8でRDBMS作ったよ
Java8でRDBMS作ったよJava8でRDBMS作ったよ
Java8でRDBMS作ったよ
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例
 
フラグを愛でる
フラグを愛でるフラグを愛でる
フラグを愛でる
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjp
 
Docker Compose 徹底解説
Docker Compose 徹底解説Docker Compose 徹底解説
Docker Compose 徹底解説
 
x86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNT
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
 
C/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールC/C++プログラマのための開発ツール
C/C++プログラマのための開発ツール
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
 
基礎線形代数講座
基礎線形代数講座基礎線形代数講座
基礎線形代数講座
 
競プロは社会の役に立たない+ベンチャー企業の話 (NPCA夏合宿OB講演).pdf
競プロは社会の役に立たない+ベンチャー企業の話 (NPCA夏合宿OB講演).pdf競プロは社会の役に立たない+ベンチャー企業の話 (NPCA夏合宿OB講演).pdf
競プロは社会の役に立たない+ベンチャー企業の話 (NPCA夏合宿OB講演).pdf
 

Similaire à AVX-512(フォーマット)詳解

BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用MITSUNARI Shigeo
 
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenIntel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenMITSUNARI Shigeo
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)Takeshi Yamamuro
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたMITSUNARI Shigeo
 
汎用性と高速性を目指したペアリング暗号ライブラリ mcl
汎用性と高速性を目指したペアリング暗号ライブラリ mcl汎用性と高速性を目指したペアリング暗号ライブラリ mcl
汎用性と高速性を目指したペアリング暗号ライブラリ mclMITSUNARI Shigeo
 
AVX命令を用いたLJの力計算のSIMD化
AVX命令を用いたLJの力計算のSIMD化AVX命令を用いたLJの力計算のSIMD化
AVX命令を用いたLJの力計算のSIMD化Hiroshi Watanabe
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011finalMikio Kubo
 
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4Takeshi Yamamuro
 
Spectre/Meltdownとその派生
Spectre/Meltdownとその派生Spectre/Meltdownとその派生
Spectre/Meltdownとその派生MITSUNARI Shigeo
 
Yet another Intel Chipset Internal SMBus device’s driver: ismt(4) (and spdmem...
Yet another Intel Chipset Internal SMBus device’s driver: ismt(4)(and spdmem...Yet another Intel Chipset Internal SMBus device’s driver: ismt(4)(and spdmem...
Yet another Intel Chipset Internal SMBus device’s driver: ismt(4) (and spdmem...Masanobu Saitoh
 
Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介MITSUNARI Shigeo
 
Unix32 v 20100508
Unix32 v 20100508Unix32 v 20100508
Unix32 v 20100508xylnao
 

Similaire à AVX-512(フォーマット)詳解 (20)

From IA-32 to avx-512
From IA-32 to avx-512From IA-32 to avx-512
From IA-32 to avx-512
 
BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用
 
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenIntel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
TVM の紹介
TVM の紹介TVM の紹介
TVM の紹介
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
汎用性と高速性を目指したペアリング暗号ライブラリ mcl
汎用性と高速性を目指したペアリング暗号ライブラリ mcl汎用性と高速性を目指したペアリング暗号ライブラリ mcl
汎用性と高速性を目指したペアリング暗号ライブラリ mcl
 
AVX命令を用いたLJの力計算のSIMD化
AVX命令を用いたLJの力計算のSIMD化AVX命令を用いたLJの力計算のSIMD化
AVX命令を用いたLJの力計算のSIMD化
 
LLVM最適化のこつ
LLVM最適化のこつLLVM最適化のこつ
LLVM最適化のこつ
 
Boost.SIMD
Boost.SIMDBoost.SIMD
Boost.SIMD
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011final
 
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
 
Spectre/Meltdownとその派生
Spectre/Meltdownとその派生Spectre/Meltdownとその派生
Spectre/Meltdownとその派生
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 
Yet another Intel Chipset Internal SMBus device’s driver: ismt(4) (and spdmem...
Yet another Intel Chipset Internal SMBus device’s driver: ismt(4)(and spdmem...Yet another Intel Chipset Internal SMBus device’s driver: ismt(4)(and spdmem...
Yet another Intel Chipset Internal SMBus device’s driver: ismt(4) (and spdmem...
 
Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介
 
ゆるバグ
ゆるバグゆるバグ
ゆるバグ
 
Unix32 v 20100508
Unix32 v 20100508Unix32 v 20100508
Unix32 v 20100508
 
Code jp2015 cpuの話
Code jp2015 cpuの話Code jp2015 cpuの話
Code jp2015 cpuの話
 

Plus de MITSUNARI Shigeo

暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学MITSUNARI Shigeo
 
範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコルMITSUNARI Shigeo
 
暗認本読書会13 advanced
暗認本読書会13 advanced暗認本読書会13 advanced
暗認本読書会13 advancedMITSUNARI Shigeo
 
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法MITSUNARI Shigeo
 
WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装MITSUNARI Shigeo
 
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化MITSUNARI Shigeo
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介MITSUNARI Shigeo
 
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用MITSUNARI Shigeo
 

Plus de MITSUNARI Shigeo (20)

暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
 
範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル
 
暗認本読書会13 advanced
暗認本読書会13 advanced暗認本読書会13 advanced
暗認本読書会13 advanced
 
暗認本読書会12
暗認本読書会12暗認本読書会12
暗認本読書会12
 
暗認本読書会11
暗認本読書会11暗認本読書会11
暗認本読書会11
 
暗認本読書会10
暗認本読書会10暗認本読書会10
暗認本読書会10
 
暗認本読書会9
暗認本読書会9暗認本読書会9
暗認本読書会9
 
暗認本読書会8
暗認本読書会8暗認本読書会8
暗認本読書会8
 
暗認本読書会7
暗認本読書会7暗認本読書会7
暗認本読書会7
 
暗認本読書会6
暗認本読書会6暗認本読書会6
暗認本読書会6
 
暗認本読書会5
暗認本読書会5暗認本読書会5
暗認本読書会5
 
暗認本読書会4
暗認本読書会4暗認本読書会4
暗認本読書会4
 
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
 
私とOSSの25年
私とOSSの25年私とOSSの25年
私とOSSの25年
 
WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装
 
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
 
楕円曲線と暗号
楕円曲線と暗号楕円曲線と暗号
楕円曲線と暗号
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介
 
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
 
集約署名
集約署名集約署名
集約署名
 

Dernier

IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価sugiuralab
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールsugiuralab
 

Dernier (7)

IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
 

AVX-512(フォーマット)詳解

  • 3. • 32個の512 bit SIMDレジスタ • zmm0, zmm1, ..., zmm31 • 一つのSIMDレジスタには整数や小数が複数入る • double(64bit) x 8, qword(64bit) x 8, float(32bit) x 16 • dword(32bit) x 16, word(16bit) x 32, byte(8bit) x 64など • 一部の整数は符号あり・符号無しを選択可能 • 下位256bitは従来のymmレジスタとしてアクセス可能 • その下位128bitは従来のxmmレジスタとしてアクセス可能 AVX-512 zmm0 ymm0 xmm0 63 31 15 0 3 / 29
  • 4. • 整数系 ; vp<演算><要素の型> dst, src1, src2 • d(dword x 32)として要素ごとにzmm2 = zmm1 + zmm0 • q(qword x 16)として要素ごとにzmm2 = zmm1 – zmm0 • 浮動小数点数系 ; v<演算><要素の型> dst, src1, src2 • pd(double x 16)として要素ごとにzmm2 = zmm1 * zmm0 • ps(float x 32)として要素ごとにzmm2 = zmm1 / zmm0 基本演算の例 vpaddd zmm2, zmm1, zmm0 vpsubq zmm2, zmm1, zmm0 vmulpd zmm2, zmm1, zmm0 vdivps zmm2, zmm1, zmm0 4 / 29
  • 5. • AVX512F(foundation) • blend, pcmp, ptest, compress等 • CD(Conflict Detection) • 競合検出 ループ処理での補助 • ER(Exponential and Reciprocal) • 指数と逆数 • PF(prefetch) • プリフェッチ • BW(byte, word), DQ(dword, qword) • VL(Vector length) • xmm, ymmレジスタ利用可能 演算グループ(1/2) 5 / 29
  • 6. • VBMI(Vector byte Manipulation Instructions) • pcompress, pexpand, pshld, vpermi2bなど • IFMA(Integer Fused Multiply Add) • 52bit整数の積の上位/下位52bitを加算 • 4FMAPS (Fused Multiply Accumulation Packed Single Precision) • 16個のfloat[]の積和演算4個を1命令で • 4VNNIW(Vector Neural Network Instructions Word variable precision) • 4個のword[]の積和(結果はdword)16個を1命令で • GFNI(Galois Field系) • 標数2の8次拡大体の元のアフィン変換/逆変換を1命令で 演算グループ(2/2) 6 / 29
  • 7. • 共通 • BAIC = AVX512{F, CD} • 主に浮動小数点数強化系 • Knights Landing = BASIC + AVX512{ER, PF} • Knights Mill = Knights Landing + AVX512_{4FMAPS, 4VNNIW} • 主に整数強化系 • Skylake = BASIC + AVX512{BW, DQ, VL} • Cannon Lake = Skylake + AVX512_{VBMI, IFMA} • Ice Lake = Cannon Lake + AVX512_{VBMI2, VNNI, GFNI, ... } 対応CPU 7 / 29
  • 8. • SIMDは特定の要素の例外処理が面倒 • AVX2までのやり方 • vcmppdで要素ごとに(a[i] > 1.0) ? (-1) : 0のマスクMを生成 • M &= a[i] ; 要素ごとにa[i] or 0 • M *= b[i] ; 要素ごとにa[i] * b[i] or 0 • vblendvpd命令で要素ごとにa[i] * b[i]かb[i]を選択 SIMDの苦手なこと double *a, *b, *c; for (int i = 0; i < n; i++) { double x = b[i]; if (a[i] > 1.0) x *= a[i]; c[i] = x; } 8 / 29
  • 9. • 要素ごとにマスク設定が可能になった • 64bitマスクレジスタk1, ..., k7 • k0もあるがマスク設定には使えない • 要素数だけマスクレジスタの下位bitが参照される • 8byte x 64なら64bit, 32byte x 16なら16bit • マスクレジスタの扱い • 該当bitが1 ; 該当要素の処理が行われる • 該当bitが0 • ゼロ化マスクなし • 操作は行われない(例外や違反は発生しない) • ゼロ化マスクあり • 0で埋められる AVX-512におけるマスク処理 9 / 29
  • 10. • vmovdqu8(byte単位のレジスタコピー) • k1レジスタのビットが立っているところだけコピー マスクの例 [Xf Xe Xd Xc Xb Xa X9 X8 X7 X6 X5 X4 X3 X2 X1 X0]xmm0 [Yf Ye Yd Yc Yb Ya Y9 Y8 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0]xmm1 [ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0]k1 [Yf Ye Yd Yc Yb Ya Y9 Y8 Y7 Y6 Y5 X4 Y3 Y2 X1 Y0]xmm1 vmovdqu8 xmm1{k1}, xmm0 10 / 29
  • 11. • vmovdqu8(byte単位のレジスタコピー) • k1レジスタのビットが立っているところだけコピー • それ以外は0クリア ゼロ化マスクの例 [Xf Xe Xd Xc Xb Xa X9 X8 X7 X6 X5 X4 X3 X2 X1 X0]xmm0 [Yf Ye Yd Yc Yb Ya Y9 Y8 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0]xmm1 [ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0]k1 [00 00 00 00 00 00 00 00 00 00 00 X4 00 00 X1 00]xmm1 vmovdqu8 xmm1{k1}{z}, xmm0 11 / 29
  • 12. • 再掲 • AVX-512のマスクレジスタを利用 先程のサンプルの例 double *a, *b, *c; for (int i = 0; i < n; i++) { double x = b[i]; if (a[i] > 1.0) x *= a[i]; c[i] = x; } // zmm2 = [1.0 ... 1.0]を設定しておく vmovups zmm0, [a] ; double x 16読み vmovups zmm1, [b] vcmppd k1, zmm2, zmm0, 1 ; k1=[(zmm2 < zmm0) ? 1 : 0] vmulpd zmm1{k1}, zmm0, zmm1 ; a[i] > 1のところだけ乗算 vmovups [c], zmm1 12 / 29
  • 13. • マスクのコスト • ロードでブレンド操作が行われるため少し低速 • デスティネーション(以下dstと略記)との依存関係が発生 • ゼロ化マスクではこの依存関係は切れる • 可能な限りゼロ化マスクを使う • メモリへの書き込みはマージmaskのみ • 書き込みアドレスが書き込み禁止領域にまたがっていても マスクレジスタでマスクされていると例外は発生しない マスクレジスタの注意点 +0 +1 +2 +3 +4 +5 +6 +7 +8|+9 +a +b +c +d +e +f [yy yy yy yy yy yy yy yy yy|xx xx xx xx xx xx xx] 書き込み禁止領域書き込み可能領域 k1 = (1 << 9) – 1のとき 13 / 29
  • 14. • 複数の条件のandやorを効率よく計算するために マスクレジスタの演算命令が追加されている • k<演算>{b,w,d,q} dst, src1, src2の形 • add, and, or, not, xor • andn(x, y) := ~(x & y) • xnor(x, y) := ~(x ^ y) • shiftl, shiftrなど • ZF, CF制御系 • kortest{b,w,d,q} src1, src2 • (src1 | src2) == 0ならZF = 1 • (src1 | src2) == ~0ならCF = 1 • vcomiss x, yよりvcomiss k, x, y; kortest k, kの方が速いらしい マスクレジスタの演算 14 / 29
  • 15. • マスクレジスタが立っているところだけ集める データ圧縮 [Xf Xe Xd Xc Xb Xa X9 X8 X7 X6 X5 X4 X3 X2 X1 X0]xmm0 [ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0]k1 [00 00 00 00 00 00 00 00 00 00 00 00 00 00 X4 X1]xmm1 vcompresspd xmm1{k1}, xmm0 15 / 29
  • 16. • a[]が正のところだけb[]につめていく データ圧縮の例 assert(n % 16 == 0); uint32_t a[n]; uint32_t b[n]; j = 0; for (int i = 0; i < n; i++) { if (a[i] > 0) { b[j++] = a[i]; } } 16 / 29
  • 17. • メイン部分 AVX-512によるデータ圧縮 // rsi = a, rdi = b, zmm0 = rax = rdx = 0 .lp: vmovdqa32 zmm1, [rsi + rax * 4] ; zmm1 = a[] vpcmpgtd k1, zmm1, zmm0 ; k1 = [(a > 0)?1:0] vpcompressd zmm2{k1}, zmm1 ; zmm2 = comp(a[]) vmovdqu32 [rdi + rdx * 4], zmm2 ; b[] = zmm2 kmovd ecx, k1 popcnt rcx, rcx ; コピーした個数だけ add rdx, rcx ; bのポインタを増やす add rax, 16 ; aは16ずつ増やす cmp rax, n jne .lp 17 / 29
  • 18. • マスクレジスタが立っているところに下から入れる データ展開 [Xf Xe Xd Xc Xb Xa X9 X8 X7 X6 X5 X4 X3 X2 X1 X0]xmm0 [ 0 0 0 1 0 0 0 0 0 1 0 1 0 0 1 0]k1 [00 00 00 X3 00 00 00 00 00 X2 00 X1 00 00 X0 00]xmm1 vcompresspd xmm1{k1}{z}, xmm0 18 / 29
  • 19. • 32 or 64bitの値をSIMDレジスタに複数個コピー • 従来 • AVX-512 • 外に{1to8}, {1to4}など • レジスタ種別(xmm/ymm/zmm)と データの型(float/double)で{1toX}のXは一意に決まる • Xbyakではptr_b[rax]と書けるようにした ブロードキャストフラグ vbroadcastss zmm0, [rax] ; [rax]のfloat1個を16個コピー vmulps zmm2, zmm1, zmm0 vmulps zmm2, zmm1, [rax]{1to16} 19 / 29
  • 20. • 従来 • 浮動小数点数の演算結果の丸め方はMXCSRレジスタに依存 • MXCSRの変更はコストが大きい • round系は小数→小数のみ, cvtt系は小数→整数の切り捨てのみ • AVX-512 • ほとんどの命令毎に丸め方を指定可能 • rne(round to nearest even) ; 最も近い偶数 • rd(round down) ; 切り下げ • ru(round up) ; 切り上げ • rz(round toward zero) ; ゼロへの丸め • 同時に例外抑制SAE(suppress all exceptions)も行われる 組み込み丸め操作 vcvtsd2si eax,xmm0,{rz-sae} ;小数→整数のゼロへの丸め 20 / 29
  • 21. • 1bitが3個の入力x, y, zに対して1bitのwを出力する関数f • f(x, y, z) = w ; fは8bit定数imm8を一つ決めると決まる • vpternlog x, y, z, imm8 ; x = f(x, y, z) imm8=e8h • 例)SHA関数の中のf(a, b, c) = ((a | b) & c) | (a & b)や f(a, b, c) = a ^ (b ^ (c ^ a))はvpternlog1命令にできる 3値論理(ternary logic) x y z w 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 1 1 0 0 0 1 0 1 1 1 1 0 1 1 1 1 1 21 / 29
  • 22. • ModR/M • mov dst, src / mov dst, [src] / mov dst, [src + disp] などの1byteエンコーディング規則 • mod • 00 ; dst, [src] • 01 ; dst, [src + disp8](8bitオフセット) • 10 ; dst, [src + disp32](32bitオフセット) • 11 ; dst, src • reg • 8種類のレジスタを3bitで指定 • r/m • srcのレジスタを指定 IA-32のフォーマット復習(1/2) [ 7 6| 5 4 3| 2 1 0] [ mod | reg | r/m ] 22 / 29
  • 23. • SIB(Scale Index Byte) • mov eax, [ecx + edx * 4 + disp]などのエンコーディング規則 • [base + index * scale + disp] • base • レジスタ種別 • index • レジスタ種別 • scale • 1, 2, 4, 8倍をそれぞれ00, 01, 10, 11で表現 IA-32のフォーマット復習(2/2) [ 7 6| 5 4 3| 2 1 0] [scale| index | base ] 23 / 29
  • 24. • modR/M + SIB • ~32bit, レジスタ8個 • REXプレフィクス(1byte) • inc/dec reg16を廃止して利用 • 64bit, レジスタ16個対応 • VEXプレフィクス(2-3byte, Vector Extension) • les, ldsの隙間を利用 • 3オペランド, 256bitレジスタ対応 • デコーダの負担を低減 • EVEXプレフィクス(4byte, Enhanced VEX) • 64bitモードで廃止されていたbound(0x62)始まり • 512bit, レジスタ32個対応 • マスクレジスタ、丸めモード、ブロードキャストなど エンコーディングの歴史 24 / 29
  • 25. • テスト • mmとppは従来のVEXプレフィクス関係 • zはゼロ化フラグ, L’Lはレジスタ長や丸めモード EVEX | EVEX | |62 P0 P1 P2| opcode ModRM/M [SIB] [Disp] [Imm] | 7 6 5 4 3 2 1 0 | P0 | R | X | B | R'| 0 | 0 | m | m | P1 | W | v | v | v | v | 1 | p | p | P2 | z | L'| L | b | V'| a | a | a | vaddpd a4a3a2a1a0,{k_aaa},b4b3b2b1b0,c4c3c2c1c0 | P0 | P1 | P2 | 62|!a3 !c4 !c3 !a4 0001|1 b3 b2 b1 b0 101|0100 !b4 aaa| | ModRM/M | <opcode> |11 a2 a1 a0 c2 c1 c0| [SIB] [Disp] 25 / 29
  • 26. • メモリアクセスのディスプレースメント(disp)は 符号つき8bit以内なら1byte, それ以外は4byte必要 • AVX-512ではzmm1個で64byteなので2個分のオフセッ ト(128)でオーバーする • これはデコーダに辛い • 通常ループアンロールなどで使うのは0x40, 0x80, 0xc0など 64byteの倍数のはず • オフセットがN(=64など)の倍数なら圧縮disp8を使う変更 圧縮disp8*N(1/2) mov rax, [rax + 0x7f] ; 48 8B 40 7F ; disp8 mov rax, [rax + 0x80] ; 48 8B 80 80 00 00 00 ; disp32 vaddpd zmm0, zmm1, [rax] ;62F1F5485800 6byte vaddpd zmm0, zmm1, [rax+0x80];62F1F548588080000000 10byte 26 / 29
  • 27. • 命令長が7byteに収まる • その代わり[rax+1]などはdisp8でなくdisp32で表現 • 余談 • 命令毎にdisp8*NのNの値のパターンが異なる • Tuple TypeはInputSizeにより変わるのでややこしい 圧縮disp8*N(2/2) vaddpd zmm0, zmm1, [rax+64] ; 62F1F548584001 vaddpd zmm0, zmm1, [rax+128]; 62F1F548584002 vaddpd zmm0, zmm1, [rax+192]; 62F1F548584003 vaddpd zmm0, zmm1, [rax+256]; 62F1F548584004 vaddpd zmm0, zmm1, [rax+1] ; 62F1F548588001000000 27 / 29
  • 28. • v4fmaddps zmm1, zmm<base>, [mem] • zmm<base>, ..., zmm<base+3>とfloat mem[4]の積和を zmm1に加算(baseは4の倍数) • zmm4を指定すればzmm4, zmm5, zmm6, zmm7が参照される • 擬似コード • デコーダの負担を減らすため? v4fmaddps(Knights Mill以降) v4fmaddps(zmm dest, zmm[base], float mem[4]) { floatX16 tmp = dest; for (j = 0; j < 4; j++) { for (i = 0; i < 16; i++) { tmp[i] += zmm[base + j][i] * msrc[j]; } dest = tmp; } } 28 / 29
  • 29. • Intelのマニュアル&エミュレータ(SDE) • https://software.intel.com/en-us/articles/intel-sdm • https://software.intel.com/en-us/articles/intel-software- development-emulator • software developer‘s manual(325383-065US)の間違い • p.1312のVSQRTPD xmm1 {k1}{z}, xmm2/m128/m32bcst などはm64bcstの間違い • Optimization Reference Manual(248966-039)の間違い • p.540のvmovaps zmm1{k1}{z}, zmm0の結果の図がおかしい • p.552の図15.5 Data Expand Operationがおかしい • @tanakmuraさんのAVX-512 Advent Calendar 2014 • https://qiita.com/advent-calendar/2014/avx512 参考文献 29 / 29