Не удалось обнаружить, почему следующий фрагмент кода не был векторизован

Я боролся с векторизации конкретного приложения на какое-то время, и я все пробовал. От autovectorization, to handcoded SSE intrinsics. Но почему-то я не могу получить ускорение на моем приложении, основанном на трафарете.

Ниже приведен фрагмент моего текущего кода, который я векторизовал с использованием встроенных функций SSE. Когда я компилирую (Intel icc), используя -vec-report3, я постоянно получаю это сообщение:
примечание: цикл не был векторизован: оператор не может быть векторизован.

  #pragma ivdep
  for ( i = STENCIL; i < z - STENCIL; i+=4 )
  {
    it = it2 + i;

    __m128 tmp2i = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j4+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j4+k*it_k])),X4_i); //loop was not vectorized: statement cannot be vectorized
    __m128 tmp3 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j3+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j3+k*it_k])),X3_i);
    __m128 tmp4 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j2+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j2+k*it_k])),X2_i);
    __m128 tmp5 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j +k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j +k*it_k])),X1_i);

    __m128 tmp6 = _mm_add_ps(_mm_add_ps(_mm_add_ps(tmp2i,tmp3),_mm_add_ps(tmp4,tmp5)), _mm_mul_ps(_mm_load_ps(&p2[it]),C00_i));

    _mm_store_ps(&tmp2[i],tmp6);

   }

Я пропустил что-то важное? Поскольку сообщение не уточняет, почему оно не может быть векторизованным, мне трудно установить узкое место.

UPDATE: После тщательного рассмотрения этих предложений я изменил код следующим образом. Я думал, что лучше всего разбить его дальше, чтобы определить утверждения, которые фактически отвечают за векторную зависимость.

//#pragma ivdep
  for ( i = STENCIL; i < z - STENCIL; i+=4 )
  {
    it = it2 + i;
    __m128 center = _mm_mul_ps(_mm_load_ps(&p2[it]),C00_i);

    u_j4 = _mm_load_ps(&p2[i+j*it_j-it_j4+k*it_k]); //Line 180
    u_j3 = _mm_load_ps(&p2[i+j*it_j-it_j3+k*it_k]);
    u_j2 = _mm_load_ps(&p2[i+j*it_j-it_j2+k*it_k]);
    u_j1 = _mm_load_ps(&p2[i+j*it_j-it_j +k*it_k]);
    u_j8 = _mm_load_ps(&p2[i+j*it_j+it_j4+k*it_k]);
    u_j7 = _mm_load_ps(&p2[i+j*it_j+it_j3+k*it_k]);
    u_j6 = _mm_load_ps(&p2[i+j*it_j+it_j2+k*it_k]);
    u_j5 = _mm_load_ps(&p2[i+j*it_j+it_j +k*it_k]);

    __m128 tmp2i = _mm_mul_ps(_mm_add_ps(u_j4,u_j8),X4_i);
    __m128 tmp3 = _mm_mul_ps(_mm_add_ps(u_j3,u_j7),X3_i);
    __m128 tmp4 = _mm_mul_ps(_mm_add_ps(u_j2,u_j6),X2_i);
    __m128 tmp5 = _mm_mul_ps(_mm_add_ps(u_j1,u_j5),X1_i);

    __m128 tmp6 = _mm_add_ps(_mm_add_ps(tmp2i,tmp3),_mm_add_ps(tmp4,tmp5));
    __m128 tmp7 = _mm_add_ps(tmp6,center);

    _mm_store_ps(&tmp2[i],tmp7);  //Line 196

   }

Когда я компилирую (icc) код выше #pragma ivdep, я получаю следующее сообщение:

remark: loop was not vectorized: existence of vector dependence.
vector dependence: assumed FLOW dependence between tmp2 line 196 and tmp2 line 196.
vector dependence: assumed ANTI dependence between tmp2 line 196 and tmp2 line 196.

Когда я компилирую (icc) его с помощью #pragma ivdep, я получаю следующее сообщение:

remark: loop was not vectorized: unsupported data type. //Line 180

Почему в Line 196 существует зависимость? Как я могу устранить предполагаемую векторную зависимость?

Ответ 1

Проблема заключается в том, что вы пытаетесь использовать автоинтеграцию вместе с ручным векторизованным кодом. Компилятор говорит, что строка не может быть векторизована, потому что вы не можете векторизовать векторную функцию.

Либо позволить компилятору автоматически векторизовать его, либо отключить автоматическую векторную нарисую, а также векторизовать свой код вручную. Как уже отмечалось, автоматический векторный анализатор будет вычислять рентабельность векторизации: он проверяет, стоит ли или нет векторизовать ваш код.