如何使用"parallel for"而不是使用几个"for"?



我正试图为sobel编写更快的代码,但我无法理解将其用于几个for循环?

我应该使用和循环数量一样多的并行for吗?

这个有效吗?

谁能解释一下代码:这里是代码:

for (int y = 0; y < Image.Height; y++)
{
for (int x = 0; x < Image.Width * 3; x += 3)
{
r_x = g_x = b_x = 0; //reset the gradients in x-direcion values
r_y = g_y = b_y = 0; //reset the gradients in y-direction values
location = x + y * ImageData.Stride; //to get the location of any pixel >> location = x + y * Stride
for (int yy = -(int)Math.Floor(weights_y.GetLength(0) / 2.0d), yyy = 0; yy <= (int)Math.Floor(weights_y.GetLength(0) / 2.0d); yy++, yyy++)
{
if (y + yy >= 0 && y + yy < Image.Height) //to prevent crossing the bounds of the array
{
for (int xx = -(int)Math.Floor(weights_x.GetLength(1) / 2.0d) * 3, xxx = 0; xx <= (int)Math.Floor(weights_x.GetLength(1) / 2.0d) * 3; xx += 3, xxx++)
{
if (x + xx >= 0 && x + xx <= Image.Width * 3 - 3) //to prevent crossing the bounds of the array
{
location2 = x + xx + (yy + y) * ImageData.Stride; //to get the location of any pixel >> location = x + y * Stride
sbyte weight_x = weights_x[yyy, xxx];
sbyte weight_y = weights_y[yyy, xxx];
//applying the same weight to all channels
b_x += buffer[location2] * weight_x;
g_x += buffer[location2 + 1] * weight_x; //G_X
r_x += buffer[location2 + 2] * weight_x;
b_y += buffer[location2] * weight_y;
g_y += buffer[location2 + 1] * weight_y;//G_Y
r_y += buffer[location2 + 2] * weight_y;
}
}
}
}
//getting the magnitude for each channel
b = (int)Math.Sqrt(Math.Pow(b_x, 2) + Math.Pow(b_y, 2));
g = (int)Math.Sqrt(Math.Pow(g_x, 2) + Math.Pow(g_y, 2));//G
r = (int)Math.Sqrt(Math.Pow(r_x, 2) + Math.Pow(r_y, 2));
if (b > 255) b = 255;
if (g > 255) g = 255;
if (r > 255) r = 255;
//getting grayscale value
grayscale = (b + g + r) / 3;
//thresholding to clean up the background
//if (grayscale < 80) grayscale = 0;
buffer2[location] = (byte)grayscale;
buffer2[location + 1] = (byte)grayscale;
buffer2[location + 2] = (byte)grayscale;
//thresholding to clean up the background
//if (b < 100) b = 0;
//if (g < 100) g = 0;
//if (r < 100) r = 0;
//buffer2[location] = (byte)b;
//buffer2[location + 1] = (byte)g;
//buffer2[location + 2] = (byte)r;
}
}

最重要的问题是:是否工作是可并行的,以及您使用的对象模型是否支持并发性。纯粹与数学相关且结果不是累积的倾向于是可并行的,但我不能评论对象模型的线程安全性。它不能保证(默认值通常是"no")。

where:

嵌套并行是没有意义的;并行有开销,放大这些开销会适得其反。对待并行最有效的方法是"块状"思考。-即相对少量的非琐碎操作(但希望至少尽可能多的可用CPU内核),而不是大量的琐碎操作。因此,放置并行性最有效的位置通常是:最外层的循环。在这种情况下,这似乎映射到图像中的行,这似乎是划分图像处理的合理方法。您可以将其划分为N个(对于CPU内核N),但老实说:我怀疑行将工作得很好,并使事情保持简单。

然而!注意,您需要避免共享状态:r_xg_xb_x以及_y部分(以及任何其他共享局部)的相同状态需要在内部声明。平行部分,确保它们是独立的。其他要看的东西:grayscale,location,location2,r,g,b,yyy,xxx。看到这些东西当前在哪里声明是很好的,但我怀疑它们都需要移动,以便在并行部分中声明。检查所有声明的局部变量,以及所有被访问的字段。

看起来bufferbuffer2只是简单的输入/输出数组,在这种情况下:它们应该在这种情况下工作正常。

相关内容

  • 没有找到相关文章

最新更新