我正在做一个学校项目,我必须优化 SSE 中的部分代码,但我现在在一个部分停留了几天。
我没有看到在此代码(它是高斯模糊算法的一部分)中使用 vector SSE 指令(内联汇编程序/instric f)的任何聪明方法。如果有人能给我一个小提示,我会很高兴
for (int x = x_start; x < x_end; ++x) // vertical blur...
{
float sum = image[x + (y_start - radius - 1)*image_w];
float dif = -sum;
for (int y = y_start - 2*radius - 1; y < y_end; ++y)
{ // inner vertical Radius loop
float p = (float)image[x + (y + radius)*image_w]; // next pixel
buffer[y + radius] = p; // buffer pixel
sum += dif + fRadius*p;
dif += p; // accumulate pixel blur
if (y >= y_start)
{
float s = 0, w = 0; // border blur correction
sum -= buffer[y - radius - 1]*fRadius; // addition for fraction blur
dif += buffer[y - radius] - 2*buffer[y]; // sum up differences: +1, -2, +1
// cut off accumulated blur area of pixel beyond the border
// assume: added pixel values beyond border = value at border
p = (float)(radius - y); // top part to cut off
if (p > 0)
{
p = p*(p-1)/2 + fRadius*p;
s += buffer[0]*p;
w += p;
}
p = (float)(y + radius - image_h + 1); // bottom part to cut off
if (p > 0)
{
p = p*(p-1)/2 + fRadius*p;
s += buffer[image_h - 1]*p;
w += p;
}
new_image[x + y*image_w] = (unsigned char)((sum - s)/(weight - w)); // set blurred pixel
}
else if (y + radius >= y_start)
{
dif -= 2*buffer[y];
}
} // for y
} // for x
最佳答案
- 您可以使用的另一个功能是逻辑运算和掩码:
例如代替:
// process only 1
if (p > 0)
p = p*(p-1)/2 + fRadius*p;
你可以写
// processes 4 floats
const __m128 &mask = _mm_cmplt_ps(p,0);
const __m128 ¬Mask = _mm_cmplt_ps(0,p);
const __m128 &p_tmp = ( p*(p-1)/2 + fRadius*p );
p = _mm_add_ps(_mm_and_ps(p_tmp, mask), _mm_and_ps(p, notMask)); // = p_tmp & mask + p & !mask
我还可以推荐您使用一个特殊的库,它会重载指令。例如:http://code.compeng.uni-frankfurt.de/projects/vc
dif
变量使内部循环的迭代依赖。您应该尝试并行化外循环。但是如果没有重载指令,代码将变得难以管理。同时考虑重新考虑整个算法。目前的看起来并不平行。也许您可以忽略精度,或者稍微增加标量时间?
关于c++ - 高斯模糊的SSE优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20666109/