7

私の最初の試みは次のようになりました(乗算したいとします)

  __m128 mat[n]; /* rows */
  __m128 vec[n] = {1,1,1,1};
  float outvector[n];
   for (int row=0;row<n;row++) {
       for(int k =3; k < 8; k = k+ 4)
       {
           __m128 mrow = mat[k];
           __m128 v = vec[row];
           __m128 sum = _mm_mul_ps(mrow,v);
           sum= _mm_hadd_ps(sum,sum); /* adds adjacent-two floats */
       }
           _mm_store_ss(&outvector[row],_mm_hadd_ps(sum,sum));
 }

しかし、これは明らかに機能しません。どうすればこれにアプローチできますか?

一度に4つロードする必要があります....

もう 1 つの質問は、配列が非常に大きい場合 (n = 1000 など)、どうすれば 16 バイトに揃えることができるでしょうか? それは可能ですか?

4

2 に答える 2

4

OK...行優先の行列規則を使用します。の各行に[m]は、8つのfloatを生成するために(2)__m128要素が必要です。8x1ベクトルvは列ベクトルです。命令を使用しているのでhaddps、SSE3が使用可能であると想定します。見つけるr = [m] * v

void mul (__m128 r[2], const __m128 m[8][2], const __m128 v[2])
{
    __m128 t0, t1, t2, t3, r0, r1, r2, r3;

    t0 = _mm_mul_ps(m[0][0], v[0]);
    t1 = _mm_mul_ps(m[1][0], v[0]);
    t2 = _mm_mul_ps(m[2][0], v[0]);
    t3 = _mm_mul_ps(m[3][0], v[0]);

    t0 = _mm_hadd_ps(t0, t1);
    t2 = _mm_hadd_ps(t2, t3);
    r0 = _mm_hadd_ps(t0, t2);

    t0 = _mm_mul_ps(m[0][1], v[1]);
    t1 = _mm_mul_ps(m[1][1], v[1]);
    t2 = _mm_mul_ps(m[2][1], v[1]);
    t3 = _mm_mul_ps(m[3][1], v[1]);

    t0 = _mm_hadd_ps(t0, t1);
    t2 = _mm_hadd_ps(t2, t3);
    r1 = _mm_hadd_ps(t0, t2);

    t0 = _mm_mul_ps(m[4][0], v[0]);
    t1 = _mm_mul_ps(m[5][0], v[0]);
    t2 = _mm_mul_ps(m[6][0], v[0]);
    t3 = _mm_mul_ps(m[7][0], v[0]);

    t0 = _mm_hadd_ps(t0, t1);
    t2 = _mm_hadd_ps(t2, t3);
    r2 = _mm_hadd_ps(t0, t2);

    t0 = _mm_mul_ps(m[4][1], v[1]);
    t1 = _mm_mul_ps(m[5][1], v[1]);
    t2 = _mm_mul_ps(m[6][1], v[1]);
    t3 = _mm_mul_ps(m[7][1], v[1]);

    t0 = _mm_hadd_ps(t0, t1);
    t2 = _mm_hadd_ps(t2, t3);
    r3 = _mm_hadd_ps(t0, t2);

    r[0] = _mm_add_ps(r0, r1);
    r[1] = _mm_add_ps(r2, r3);
}

アラインメントに関しては、タイプ__m128の変数がスタック上で自動的にアラインメントされる必要があります。動的メモリでは、これは安全な仮定ではありません。一部のmalloc/新しい実装では、8バイトで整列されることが保証されているメモリのみが返される場合があります。

組み込みヘッダーは、_mm_mallocと_mm_freeを提供します。この場合、alignパラメーターは(16)である必要があります。

于 2011-11-28T11:52:34.247 に答える
2

Intel は、1×1 から 6×6 までのサイズの行列用のSmall Matrix Libraryを開発しました。アプリケーション ノートAP-930 ストリーミング SIMD 拡張命令 - 行列乗算では、2 つの 6×6 行列を乗算するアルゴリズムについて詳しく説明しています。これは、多少の努力で他のサイズのマトリックスに適応できるはずです。

于 2011-11-27T13:59:46.057 に答える