使用TBB优化具有少量指令(SSE2,SSE4)的循环

时间:2011-02-10 02:58:08

标签: optimization image-processing parallel-processing tbb sse2

我有一个简单的图像处理相关算法。 简而言之,浮点图像(平均值)由8位图像减去 结果然后保存到浮动图像(dest)

此函数主要由内在函数编写。

我尝试用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);
}

1 个答案:

答案 0 :(得分:1)

相对于加载和存储的数量,这里几乎没有进行任何计算,因此您很可能受到内存带宽而非计算的限制。这可以解释为什么在优化计算时没有看到吞吐量有任何改进。

我会尽快摆脱_mm_prefetch指令 - 他们几乎肯定没有帮助,甚至可能会损害表现。

如果可能的话,你应该将这个循环与你之前/之后正在进行的任何其他操作结合起来 - 这样就可以通过更多的计算来分摊内存I / O的成本。