1

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

该函数主要由内部函数编写。

我曾尝试使用 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 回答