2

だから私は次のような配列操作をしようとしていました

for (int i=0;i++i<32)
{
    output[offset+i] += input[i];
}

ここでoutput、およびinputfloat配列です(これは、のおかげで16バイトに整列されますmalloc)。しかし、私はそれを保証することはできませんoffset%4=0。これらの位置合わせの問題をどのように修正できるのか疑問に思いました。

私は

while (offset+c %4 != 0)
{
    c++;
    output[offset+c] += input[c];
}

整列されたループが続きます-に整列されていないアクセスが必要なため、これは明らかに機能しませんinput

元のループをベクトル化する方法はありますか?

4

1 に答える 1

5

コメントを回答に移動する:

位置合わせされていないメモリ アクセス用の SSE 命令があります。これらは、次の組み込み関数を介してアクセスできます。

doubleすべてのおよび 整数型についても同様です。

したがって、アライメントを保証できない場合は、これが簡単な方法です。可能であれば、理想的な解決策は、この問題を完全に回避できるように、配列を最初から調整することです。

アクセスのミスアラインメントによるパフォーマンスの低下は依然としてありますが、非常に乱雑なシフト/シャッフル ハック ( など_mm_alignr_epi8()) に頼らない限り、避けられません。

_mm_loadu_psandを使用したコード_mm_storeu_ps- これは、実際には gcc が単独で行うよりも 50% 遅くなります。

for (int j=0;j<8;j++)
{
    float* out = &output[offset+j*4];
    __m128 in = ((__m128*)input)[j]; //this is aligned so no need for _mm_loadu_ps
    __m128 res  = _mm_add_ps(in,_mm_loadu_ps(out)); //add values 
    _mm_storeu_ps(out,res); //store result
}
于 2012-04-24T03:24:46.297 に答える