Optimization 使用TBB优化少指令循环(SSE2、SSE4)
我有一个简单的图像处理相关算法。 简单地说,浮点图像(平均值)减去8位图像 然后将结果保存到浮点图像(dest) 此函数主要由intrinsic编写 我试着用TBB优化这个函数,Parralell_, 但我在速度上没有得到任何提高,只有受到点球 我该怎么办?我是否应该使用更低级的方案,如TBB任务 优化代码Optimization 使用TBB优化少指令循环(SSE2、SSE4),optimization,image-processing,parallel-processing,tbb,sse2,Optimization,Image Processing,Parallel Processing,Tbb,Sse2,我有一个简单的图像处理相关算法。 简单地说,浮点图像(平均值)减去8位图像 然后将结果保存到浮点图像(dest) 此函数主要由intrinsic编写 我试着用TBB优化这个函数,Parralell_, 但我在速度上没有得到任何提高,只有受到点球 我该怎么办?我是否应该使用更低级的方案,如TBB任务 优化代码 float *m, **m_data, *o, **o_data; unsigned char *p, **src_data; reg
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);
}
float*m,**m_数据,
*o、 **o_数据;
无符号字符*p,**src_数据;
注册无符号长len,i;
无符号长nr,
数控;
src_data=src->UByteData;//二维阵列
m_data=mean->FloatData;//二维阵列
o_data=dest->FloatData;//二维阵列
nr=src->Rows;
nc=src->Cols;
__m128i-xmm0;
对于(i=0;i相对于加载和存储的数量,您在这里几乎没有进行任何计算,因此您很可能受到内存带宽而不是计算的限制。这可以解释为什么在优化计算时,您没有看到吞吐量的任何改善
不过,我会去掉\u mm_prefetch
指令——它们几乎肯定在这里没有帮助,甚至可能会影响性能
如果可能的话,您应该将此循环与在此之前/之后执行的任何其他操作结合起来,这样您就可以在更多的计算中分摊内存I/O的成本。相对于加载和存储的数量,您在这里几乎没有进行计算,因此您很可能受到内存带宽而不是计算的限制这可以解释为什么在优化计算时,吞吐量没有任何提高
不过,我会去掉\u mm_prefetch
指令——它们几乎肯定在这里没有帮助,甚至可能会影响性能
如果可能的话,您应该将此循环与在此之前/之后执行的任何其他操作结合起来,这样您就可以在更多的计算中分摊内存I/O的成本。如果IPP已经有了用于此操作的函数,我也不会感到惊讶。如果您使用的是英特尔编译器,为什么不编写一个简单版本的函数,看看mpiler可以自己矢量化吗?我不知道GCC在这方面的情况。如果IPP已经有了这个函数,我也不会感到惊讶。如果您使用的是英特尔编译器,为什么不编写一个简单版本的函数,看看编译器是否可以自己矢量化呢?我不知道GCC在这方面的情况。为什么预取在这方面没有用处case?@prgbenz:_mm_预取需要在任何潜在缓存未命中之前发出几百个时钟周期,并且只有在您有空闲带宽的情况下才有帮助-将其放在相关负载之前不会有任何帮助,甚至可能会影响CPU可能已经在执行的任何自动预取。除此之外,它还浪费周期在已经很短的循环中。为什么预取在这种情况下没有用处?@prgbenz:_mm_预取需要在任何潜在缓存未命中之前发出几百个时钟周期,并且只有当您有空闲带宽时才有帮助-将其放在相关加载之前不会有帮助,甚至可能会影响任何自动缓存重新蚀刻CPU可能已经在做的事情。除此之外,它在已经相当短的循环中浪费周期。