1

私は単純な画像処理関連のアルゴリズムを持っています。簡単に説明すると、float内の画像(平均)が8ビット画像によって減算され、結果がfloat画像(宛先)に保存されます。

この関数は主に組み込み関数によって書かれています。

TBB、parrallel_forを使用してこの関数を最適化しようとしましたが、速度は向上しませんでしたが、ペナルティが発生しました。

私は何をすべきか ?コードを最適化するために、TBBタスクなどのより低レベルのスキームを使用する必要がありますか?

float           *m, **m_data,
                *o, **o_data;
unsigned char   *p, **src_data;
register unsigned long len, i;
unsigned long   nr,
                nc;

src_data    =   src->UByteData;    // 2d array
m_data      =   mean->FloatData;   // 2d array
o_data      =   dest->FloatData;   // 2d array
nr          =   src->Rows;
nc          =   src->Cols;

__m128i xmm0;

for(i=0; i<nr; i++)
{
    m = m_data[i];
    o = o_data[i];
    p = src_data[i];
    len = nc;
    do
    {
        _mm_prefetch((const char *)(p + 16),  _MM_HINT_NTA);
        _mm_prefetch((const char *)(m + 16),  _MM_HINT_NTA);

        xmm0 = _mm_load_si128((__m128i *) (p));

        _mm_stream_ps(
                        o,
                        _mm_sub_ps(
                                    _mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_srli_si128(xmm0, 0))),
                                    _mm_load_ps(m + offset)
                                )
                    );
        _mm_stream_ps(
                        o + 4,
                        _mm_sub_ps(
                                    _mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_srli_si128(xmm0, 4))),
                                    _mm_load_ps(m + offset + 4)
                                )
                    );
        _mm_stream_ps(
                        o + 8,
                        _mm_sub_ps(
                                    _mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_srli_si128(xmm0, 8))),
                                    _mm_load_ps(m + offset + 8)
                                )
                    );
        _mm_stream_ps(
                        o + 12,
                        _mm_sub_ps(
                                    _mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_srli_si128(xmm0, 12))),
                                    _mm_load_ps(m + offset + 12)
                                )
                    );

        p += 16;
        m += 16;
        o += 16;
        len -= 16;
    }
    while(len);
}
4

1 に答える 1

1

ここでは、ロードとストアの数に比べてほとんど計算を行っていないため、計算ではなくメモリ帯域幅によって制限されている可能性があります。これは、計算を最適化したときにスループットの改善が見られない理由を説明します。

しかし、私は指示を取り除くでしょう_mm_prefetch-それらはほぼ確実にここで助けにはならず、パフォーマンスを損なうことさえあるかもしれません。

可能であれば、このループを、この前後に実行している他の操作と組み合わせる必要があります。そうすることで、より多くの計算でメモリI/Oのコストを償却できます。

于 2011-02-10T08:46:30.073 に答える