Intel Architecture Instruction Set Extensions Programming Referenceのセクション 2.5.3「Broadcasts」では、AVX512 (および Knights Corner) が
一部のロード操作命令、つまり、メモリからデータをロードし、何らかの計算またはデータ移動操作を実行する命令のデータ ブロードキャストをエンコードするためのビット フィールド。
たとえば、Intel アセンブリ構文を使用して、格納されているアドレスでスカラーをブロードキャストrax
し、16 個の浮動小数点数で乗算して、結果を次のようzmm2
に書き込むことができます。zmm1
vmulps zmm1, zmm2, [rax] {1to16}
ただし、これを実行できる組み込み関数はありません。したがって、組み込み関数を使用すると、コンパイラは折りたたむことができるはずです
__m512 bb = _mm512_set1_ps(b);
__m512 ab = _mm512_mul_ps(a,bb);
単一の命令に
vmulps zmm1, zmm2, [rax] {1to16}
しかし、私はGCCがこれを行っていることを観察していません。これに関する GCC バグ レポートを見つけました。
GCC を使用した FMA で同様のことを確認しました。たとえば、GCC 4.9 は_mm256_add_ps(_mm256_mul_ps(areg0,breg0)
、-Ofast
. ただし、GCC 5.1 では現在、単一の fma に折りたたまれています。少なくとも、FMA でこれを行う組み込み関数があります_mm256_fmadd_ps
。しかし、例えば_mm512_mulbroad_ps(vector,scalar)
本質的なものはありません。
GCC はいずれこれを修正するかもしれませんが、それまではアセンブリが唯一の解決策です。
私の質問は、GCC のインライン アセンブリでこれを行う方法ですか?
上記の例の GCC インライン アセンブリの正しい構文を思いついたかもしれません (ただし、よくわかりません)。
"vmulps (%%rax)%{1to16}, %%zmm1, %%zmm2\n\t"
私は本当にこのような機能を探しています
static inline __m512 mul_broad(__m512 a, float b) {
return a*b;
}
どこで ifb
はメモリ内にあり、その中のポイントがrax
生成されます
vmulps (%rax){1to16}, %zmm0, %zmm0
ret
その中にある場合b
はxmm1
生成されます
vbroadcastss %xmm1, %zmm1
vmulps %zmm1, %zmm0, %zmm0
ret
GCC はすでにvbroadcastss
組み込み関数を使用して -from-register ケースを実行しますが、メモリ内にある場合は、これをfrom メモリb
にコンパイルします。vbroadcastss
__m512 mul_broad(__m512 a, float b) {
__m512 bb = _mm512_set1_ps(b);
__m512 ab = _mm512_mul_ps(a,bb);
return ab;
}
メモリ内にある場合、clang はブロードキャスト メモリ オペランドを使用b
します。