2012-07-16 6 views
11

私はいつか特定のアプリケーションをベクトル化するのに苦労しています。オートベクトル化から、手作業によるSSE組み込み関数へ。しかし、何とか私はステンシルベースのアプリケーションでスピードアップを得ることができません。以下のコードがベクトル化されていなかった理由を検出できません。

以下は、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); 

    } 

私は重要な何かが足りないのですか?なぜメッセージがベクトル化できないのか、メッセージが複雑ではないので、私はボトルネックを突き止めるのが難しいと思っています。

更新: 提案を慎重に検討した後、私は次のようにコードを微調整しました。私はそれをさらに分解して、実際にベクトル依存関係の原因となっているステートメントを特定することを最善と考えました。私は(ICC)私は、次のメッセージを取得#pragma ivdepせずに上記のコードをコンパイルするとき

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

    } 

#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)は、それが、私は、次のメッセージを取得する:

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

196行目にはなぜ依存関係がありますか?提案されたベクトルの依存関係をどのように排除できますか?

+0

最終値とループ数を事前に計算して 'for'構造を単純化します。 –

+0

既にベクトル化しているため、ベクトル化できません。計算/メモリアクセス率が低すぎるため、スピードアップが得られません。 – Mysticial

+0

私は最初の考えであったアラインメントではありませんが、アレイオフセットの式を簡素化することから始める価値があります。 –

答えて

2

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

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

関連する問題