Оптимизация кода с использованием встроенных функций Intel SSE для векторизации

Я впервые работаю с внутренними функциями SSE. Я пытаюсь преобразовать простой фрагмент кода в более быструю версию, используя intel SSE intrinsic (до 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

      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. Я очень новичок в этом и не знаю, как с этим поступить.

Пожалуйста, помогите мне определить правильный подход к обработке этого кода.

14
задан Michiel uit het Broek 29 January 2019 в 12:40
поделиться