質問

仮に私は非常に単純なコードのように:

double array[SIZE_OF_ARRAY];
double sum = 0.0;

for (int i = 0; i < SIZE_OF_ARRAY; ++i)
{
    sum += array[i];
}

については基本的に行いたい同じ操作をSSE2.する方法を教えてください。

役に立ちましたか?

解決

こちらはシンプルなSSE3実施

#include <emmintrin.h>

__m128d vsum = _mm_set1_pd(0.0);
for (int i = 0; i < n; i += 2)
{
    __m128d v = _mm_load_pd(&a[i]);
    vsum = _mm_add_pd(vsum, v);
}
vsum = _mm_hadd_pd(vsum, vsum);
double sum = _mm_cvtsd_f64(vsum0);

できunrollループを取得しい性能により複数のアキュムレータの非表示の遅延のFPのほか(このように日@Mysticial).Unrollの3倍から4倍近くに複数の"和"をベクトルにボトルネックの負荷およびFP-追加-ハイスループット(つりの時計サイクルではなくFP-追加遅延(3または4サイクル):

__m128d vsum0 = _mm_setzero_pd();
__m128d vsum1 = _mm_setzero_pd();
for (int i = 0; i < n; i += 4)
{
    __m128d v0 = _mm_load_pd(&a[i]);
    __m128d v1 = _mm_load_pd(&a[i + 2]);
    vsum0 = _mm_add_pd(vsum0, v0);
    vsum1 = _mm_add_pd(vsum1, v1);
}
vsum0 = _mm_add_pd(vsum0, vsum1);    // vertical ops down to one accumulator
vsum0 = _mm_hadd_pd(vsum0, vsum0);   // horizontal add of the single register
double sum = _mm_cvtsd_f64(vsum0);

この配列 a は16バイト整列の要素数 n を仮定しているので2の倍数ですので(または4の場合には、丸められないループ).

参照 最速い水平floatベクトル和x86 代替を行い、平和社外のループを実行します。SSE3企業のホームページへリンクが完全にユニバーサル(特にAMD Cpuための支援をすることによIntel).

また、 _mm_hadd_pd 通常はインターネットには想像もつかなものCpuを支えて下さっているので、SSE2-みなが悪くなって来ているので現代のCpuを搭載しています。この外部にループしないんでみたいという気持ちになり差はなかった。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top