11

しばらくの間、特定のアプリケーションのベクトル化に苦労しており、すべてを試しました。自動ベクトル化からハンドコーディングされた SSE 組み込みまで。しかし、どういうわけか、ステンシル ベースのアプリケーションで高速化を実現できません。

以下は、SSE 組み込み関数を使用してベクトル化した現在のコードのスニペットです。-vec-report3 を使用してコンパイル (Intel icc) すると、常に次のメッセージが表示されます: remark
: loop was not vectorized: statement cannot be vectorized.

  #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);

   }

私は何か重要なものを見逃していますか?ベクトル化できない理由がメッセージで詳しく説明されていないため、ボトルネックを特定するのが難しいと感じています。

更新: 提案を慎重に検討した後、次のようにコードを微調整しました。ベクトル依存の実際の原因となっているステートメントを特定するには、さらに分解するのが最善だと考えました。

//#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

ライン 196 に依存性が示唆されているのはなぜですか? 提案されたベクトル依存をどのように排除できますか?

4

1 に答える 1

2

問題は、手動でベクトル化されたコードと一緒に自動ベクトル化を使用しようとしていることです。コンパイラーは、ベクトル関数をベクトル化できないため、行をベクトル化できないと言います。

コンパイラーに自動ベクトル化させるか、自動ベクトル化を無効にして手動でコードをベクトル化してください。既にコメントしたように、自動ベクトライザーはベクトル化の収益性を計算します。コードをベクトル化する価値があるかどうかをチェックします。

于 2013-02-26T01:51:08.197 に答える