Intel Advanced Vector Extensions (AVX) は、倍精度浮動小数点変数の 256 ビット バージョン (YMM レジスタ) で内積を提供しません。「なんで?」質問は、別のフォーラム (ここ) とスタック オーバーフロー (ここ) で非常に簡単に扱われています。しかし、私が直面している問題は、この不足している命令を他の AVX 命令に効率的に置き換える方法です。
256 ビット バージョンの内積は、単精度浮動小数点変数用に存在します (ここを参照)。
__m256 _mm256_dp_ps(__m256 m1, __m256 m2, const int mask);
アイデアは、この不足している命令に相当する効率的なものを見つけることです。
__m256d _mm256_dp_pd(__m256d m1, __m256d m2, const int mask);
__m128
より具体的には、 (4 つの float) から(4 つの double)に変換したいコードでは__m256d
、次の命令を使用します。
__m128 val0 = ...; // Four float values
__m128 val1 = ...; //
__m128 val2 = ...; //
__m128 val3 = ...; //
__m128 val4 = ...; //
__m128 res = _mm_or_ps( _mm_dp_ps(val1, val0, 0xF1),
_mm_or_ps( _mm_dp_ps(val2, val0, 0xF2),
_mm_or_ps( _mm_dp_ps(val3, val0, 0xF4),
_mm_dp_ps(val4, val0, 0xF8) )));
このコードの結果は、と、 、 、、との間_m128
の内積の結果を含む 4 つの float のベクトルです。val1
val0
val2
val0
val3
val0
val4
val0
多分これは提案のためのヒントを与えることができますか?