SSE組み込み関数を扱うのはこれが初めてです。Intel SSE組み込み型(SSE4.2まで)を使用して、単純なコードをより高速なバージョンに変換しようとしています。いくつかのエラーが発生したようです。
コードのスカラーバージョンは次のとおりです:(単純な行列の乗算)
void mm(int n, double *A, double *B, double *C)
{
int i,j,k;
double tmp;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
tmp = 0.0;
for(k = 0; k < n; k++)
tmp += A[n*i+k] *
B[n*k+j];
C[n*i+j] = tmp;
}
}
これは私のバージョンです:私は含まれています#include <ia32intrin.h>
void mm_sse(int n, double *A, double *B, double *C)
{
int i,j,k;
double tmp;
__m128d a_i, b_i, c_i;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
tmp = 0.0;
for(k = 0; k < n; k+=4)
a_i = __mm_load_ps(&A[n*i+k]);
b_i = __mm_load_ps(&B[n*k+j]);
c_i = __mm_load_ps(&C[n*i+j]);
__m128d tmp1 = __mm_mul_ps(a_i,b_i);
__m128d tmp2 = __mm_hadd_ps(tmp1,tmp1);
__m128d tmp3 = __mm_add_ps(tmp2,tmp3);
__mm_store_ps(&C[n*i+j], tmp3);
}
}
私はこれでどこが間違っているのですか?次のようなエラーが発生します。
mm_vec.c(84):エラー:タイプ「int」の値をタイプ「__m128d」のエンティティに割り当てることはできませんa_i = __mm_load_ps(&A [n * i + k]);
これが私がコンパイルしている方法です:icc -O2 mm_vec.c -o vec
誰かがこのコードを正確に変換するのを手伝ってくれませんか。ありがとう!
アップデート:
あなたの提案によると、私は次の変更を加えました:
void mm_sse(int n, float *A, float *B, float *C)
{
int i,j,k;
float tmp;
__m128 a_i, b_i, c_i;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
tmp = 0.0;
for(k = 0; k < n; k+=4)
a_i = _mm_load_ps(&A[n*i+k]);
b_i = _mm_load_ps(&B[n*k+j]);
c_i = _mm_load_ps(&C[n*i+j]);
__m128 tmp1 = _mm_mul_ps(a_i,b_i);
__m128 tmp2 = _mm_hadd_ps(tmp1,tmp1);
__m128 tmp3 = _mm_add_ps(tmp2,tmp3);
_mm_store_ps(&C[n*i+j], tmp3);
}
}
しかし、今はセグメンテーション違反が発生しているようです。おそらく、配列A、B、Cの配列添え字に適切にアクセスしていないため、これを知っています。私はこれに非常に慣れていないので、これをどのように進めるかわかりません。
このコードを処理するための正しいアプローチを決定するのを手伝ってください。