私は、実数、虚数、実数、虚数など4つの単精度複素数を含む256ビットAVXレジスタを持っています。現在、256ビットレジスタ全体をメモリに書き戻して合計していますが、それは非効率的です。AVX、単精度複素数の水平方向の合計?
AVX(またはAVX2)組み込み関数を使用して複素数水平和を実行するにはどうすればよいですか?組み込み関数を使って同等の効率で答えがない場合は、アセンブリを使って答えを受け取ります。
編集:レジスタにAR、AI、BR、BI、CR、CI、DR、DIが含まれている場合は、複素数(AR + BR + CR + DR、AI + BI + CI) + DI)。結果が256ビットレジスタにある場合は、2つの単精度浮動小数点数を抽出できます。
EDIT2:だけAVX(ないAVX2)を必要と潜在的なソリューション、必ずしも最適ではないけれども...
float hsum_ps_sse3(__m128 v) {
__m128 shuf = _mm_movehdup_ps(v); // broadcast elements 3,1 to 2,0
__m128 sums = _mm_add_ps(v, shuf);
shuf = _mm_movehl_ps(shuf, sums); // high half -> low half
sums = _mm_add_ss(sums, shuf);
return _mm_cvtss_f32(sums);
}
float sumReal = 0.0;
float sumImaginary = 0.0;
__m256i mask = _mm256_set_epi32 (7, 5, 3, 1, 6, 4, 2, 0);
// Separate real and imaginary.
__m256 permutedSum = _mm256_permutevar8x32_ps(sseSum0, mask);
__m128 realSum = _mm256_extractf128_ps(permutedSum , 0);
__m128 imaginarySum = _mm256_extractf128_ps(permutedSum , 1);
// Horizontally sum real and imaginary.
sumReal = hsum_ps_sse3(realSum);
sumImaginary = hsum_ps_sse3(imaginarySum);
私たちはコードサイトです。単純な例を使って、より簡単に望むものを説明することができます。つまり、私は問題を抱えています。はい、AVXは2レーンの非常識なデザインですが、この場合は怪我をしません。実部品を1つのレーンにシャッフルし、もう一方のレーンに仮想コンポーネント(ビット0:127と128:255)を追加し、レーン内で水平に追加します。結果は0:31と128:159になります。 – MSalters
あなたの目標は何ですか?たぶん、2つのAVXレジスタに8つの複素数を格納することを検討したいと思います。1つの実数部分と別のAVXレジスタの虚数部分です。本当にあなたの目標が何であるかによって異なります。 –
@ Zboson私の目標は、質問に記載されているとおりです。実数と虚数の値が交互に変わるようにデータが格納され、これは変更できません。私の編集で提案した解決策は、実数と虚数成分を合計するためにそれらの成分を分離しますが、入力データは実数と虚数の交互になります。 – user1777820