2

このような内部ループがあります

for(i=0 ;i<n;i++){
 x[0] += A[i] * z[0];
 x[1] += A[i] * z[1];
 x[2] += A[i] * z[2];
 x[3] += A[i] * z[3];
}

内側の 4 つの命令は、コンパイラによって SSE 命令に簡単に変換できます。現在のコンパイラはこれを行いますか? 彼らがそうする場合、コンパイラでこれを強制するために私は何をしなければなりませんか?

4

2 に答える 2

4

あなたが提供したものから、これはベクトル化できません。これは、ポインターが互いにエイリアスになる可能性があるためです。つまり、x配列がAorとオーバーラップする可能性がありzます。

xコンパイラを支援する簡単な方法は、 as として宣言すること__restrictです。別の方法は、次のように書き直すことです。

for(i=0 ;i<n;i++)
{
 float Ai=A[i];
 float z0=z[0], z1=z[1], z2=z[2], z3=z[3];
 x[0] += Ai * z0;
 x[1] += Ai * z1;
 x[2] += Ai * z2;
 x[3] += Ai * z3;
}

私は実際にコンパイラーにコードを自動ベクトル化させようとしたことがないので、それができるかどうかはわかりません。ベクトル化されなくても、ロードヒットストアを発生させることなく、ロードとストアをより効率的に順序付けできるため、高速になるはずです。

コンパイラよりも多くの情報がある場合 (たとえば、ポインターが 16 バイトでアラインされているかどうか)、それを有利に使用できるはずです (たとえば、アラインされたロードを使用する)。コンパイラよりも多くのことを知っている場合にのみ、常にコンパイラを打ち負かすようにすべきだと言っているわけではないことに注意してください。

参考文献:

于 2011-07-06T05:16:26.003 に答える