6

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

その中にある場合bxmm1生成されます

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します。

4

1 に答える 1