20

4つの64ビット浮動小数点値のパックされたベクトルがあります。
ベクトルの要素の合計を取得したいと思います。

SSEを使用すると(および32ビットフロートを使用して)、次のことができます。

v_sum = _mm_hadd_ps(v_sum, v_sum);
v_sum = _mm_hadd_ps(v_sum, v_sum);

残念ながら、AVXは_mm256_hadd_pd命令を備えていますが、SSEバージョンとは結果が異なります。これは、ほとんどのAVX命令が、128ビットの境界を越えることなく、128ビットの下位および上位ごとに別々にSSE命令として機能するためだと思います。

理想的には、私が探しているソリューションは次のガイドラインに従う必要があります
。1)AVX/AVX2命令のみを使用します。(SSEなし)
2)2〜3回以内の指示でそれを行います。

ただし、(上記のガイドラインに従わなくても)効率的でエレガントな方法は常に受け入れられています。

助けてくれてありがとう。

-ルイジカステッリ

4

3 に答える 3

28

2つの__m256dベクトルがx1ありx2、それぞれdoubleに水平方向に合計する4つのが含まれている場合は、次のように実行できます。

__m256d x1, x2;
// calculate 4 two-element horizontal sums:
// lower 64 bits contain x1[0] + x1[1]
// next 64 bits contain x2[0] + x2[1]
// next 64 bits contain x1[2] + x1[3]
// next 64 bits contain x2[2] + x2[3]
__m256d sum = _mm256_hadd_pd(x1, x2);
// extract upper 128 bits of result
__m128d sum_high = _mm256_extractf128_pd(sum1, 1);
// add upper 128 bits of sum to its lower 128 bits
__m128d result = _mm_add_pd(sum_high, _mm256_castpd256_pd128(sum));
// lower 64 bits of result contain the sum of x1[0], x1[1], x1[2], x1[3]
// upper 64 bits of result contain the sum of x2[0], x2[1], x2[2], x2[3]

したがって、3つの命令が必要な水平方向の合計の2つを実行するように見えます。上記はテストされていませんが、概念を理解する必要があります。

于 2012-03-19T19:24:24.307 に答える
4

合計だけが必要で、少しのスカラー コードが許容される場合:

__m256d x;
__m256d s = _mm256_hadd_pd(x,x);
return ((double*)&s)[0] + ((double*)&s)[2];
于 2013-12-05T01:39:08.700 に答える