私はいつか特定のアプリケーションをベクトル化するのに苦労しています。オートベクトル化から、手作業による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行目にはなぜ依存関係がありますか?提案されたベクトルの依存関係をどのように排除できますか?
最終値とループ数を事前に計算して 'for'構造を単純化します。 –
既にベクトル化しているため、ベクトル化できません。計算/メモリアクセス率が低すぎるため、スピードアップが得られません。 – Mysticial
私は最初の考えであったアラインメントではありませんが、アレイオフセットの式を簡素化することから始める価値があります。 –