0

~を計算しk=0たいk=100

A[j][k]=((A[j][k]-con*A[r][k])%2);

(con*A[r][k])そのため、いくつかに保存しint temp[5] てからA[j][k]-temp[]、SIMD で次のコードで何が問題なのかを 実行しています。__m128i m5=_mm_sub_epi32(*m3,*m4);

while((k+4)<100)
{       
    __m128i *m3 = (__m128i*)A[j+k]; 

    temp[0]=con*A[r][k];
    temp[1]=con*A[r][k+1];
    temp[2]=con*A[r][k+2];
    temp[3]=con*A[r][k+3];

    __m128i *m4 = (__m128i*)temp;
    __m128i m5 =_mm_sub_epi32(*m3,*m4);
    (temp_ptr)=(int*)&m5;
    printf("%ld,%d,%ld\n",A[j][k],con,A[r][k]);

    A[j][k]  =temp_ptr[0]%2;
    A[j][k+1]=temp_ptr[1]%2;
    A[j][k+2]=temp_ptr[2]%2;
    A[j][k+3]=temp_ptr[3]%2;

    k=k+4;
}
4

3 に答える 3

2

ほとんどの場合、配置を気にしていませんでした。SIMD 命令には 16 バイトのアラインメントが必要です (この記事を参照)。そうしないと、プログラムがクラッシュします。

アラインメントか、どこかに間違ったインデックスがあり、間違ったメモリにアクセスしています。

于 2012-05-01T19:14:07.203 に答える
1

j、k、およびrの可能な値がないと、理由を判断するのは困難ですが、配列の1つにインデックスを付けすぎている可能性があります。

于 2012-05-01T18:41:47.410 に答える
0

実装する場合:

for (k = 0; k < 100; k += 4)
{
    A[j][k] = (A[j][k] - con * A[r][k]) % 2;
}

SIMDのメリットを知りたい場合は、すべてSIMDで行う必要があります。つまり、SIMDとスカラーコードを混在させないでください。

例(未テスト):

const __m128i vcon = _mm_set1_epi32(con);
const __m128i vk1 = _mm_set1_epi32(1);
for (k = 0; k < 100; k += 4)
{
    __m128i v1 = _mm_loadu_si128(&A[j][k]); // load v1 from A[j][k..k+3] (misaligned)
    __m128i v2 = _mm_loadu_si128(&A[r][k]); // load v2 from A[r][k..k+3] (misaligned)

    v2 = _mm_mullo_epi32(v2, vcon);         // v2 = con * A[r][k..k+3]
    v1 = _mm_sub_epi32(v1, v2);             // v1 = A[j][k..k+3] - con * A[r][k..k+3]
    v1 = _mm_and_si128(v1, vk1);            // v1 = (A[j][k..k+3] - con * A[r][k..k+3]) % 2

    _mm_storeu_si128(&A[j][k], v1);         // store v1 back to A[j][k..k+3] (misaligned)
}

注:Aの各行が16バイトに整列されていることを保証できる場合は、整列されていないロード/ストア(_mm_loadu_si128/ _mm_storeu_si128)を整列されたロード/ストア(_mm_load_si128/ )に変更でき_mm_store_si128ます。これにより、ターゲットとするCPUに応じて、パフォーマンスがいくらか向上します。

于 2012-05-01T20:32:53.703 に答える