分割位图以进行并行处理

Dividing a Bitmap for Parallel Processing

我将如何将位图划分为多个段并用于并行处理?我已经有了位图的高度和宽度,但从这里开始。我读过使用 MPI_Cart_shift()MPI_Sendrecv()。但是,我不确定如何使用它们。

  width = BMP_GetWidth (bmp);  
  height = BMP_GetHeight (bmp);
  new_bmp = BMP_Create(width, height, 24); // BMP_Create(UINT width, UINT height, USHORT depth)

我如何将位图划分为多个段以用于并行处理取决于正在进行的处理类型。

你的标签(但不是你的问题)提到了高斯模糊,所以这可能是一个很好的起点。

对于高斯模糊,每个输出像素都依赖于大量输入像素,仅此而已。如果每个处理器都有所有输入像素的(只读)副本,那么您可以根据需要拆分工作,但 "banding" 效果最好。具体来说,如果有 N 个处理器,第一个处理器将找到第一组 "total_pixels/N" 输出像素(可能是图像顶部的像素带),第二个处理器将执行第二组"total_pixels/N" 输出像素(可能是第一个波段下方的像素波段)等。完成所有处理器后,您只需按正确的顺序附加每个处理器的输出像素即可获得整个输出位图。

请注意(由于四舍五入)某些处理器可能需要处理不同数量的像素 - 例如如果位图有 10000 个像素并且你有 64 个处理器,那么“10000/64 = 156.25”但是一个处理器不能做四分之一像素,所以你最终有 48 个处理器做 156 个像素,而 16 个处理器做 157 个像素( "48*156 + 16*157 = 10000").

此外,如果处理器的速度可能不同 and/or 不同的延迟,您可能希望将工作分成更多部分(例如,如果有 64 个处理器将工作分成 128 个部分,较慢的处理器可能只做 1 件,而更快的处理器可能做 4 件。

如果处理器还没有所有输入像素的副本(并且如果没有共享内存),那么您可以向每个处理器发送所有像素的一小部分。例如,如果您有一个 7 行高的高斯矩阵(输出位置上方 3 行,输出位置上方 1 行,输出位置下方 3 行),并且如果每个处理器输出 100 行像素的波段,则你会向每个处理器发送一个“3+100+3 = 106”的输入像素波段来处理(除了处理第一个波段和最后一个波段的处理器,它们只会得到“3+100”或“100+” 3" 行输入像素)。

对于像(例如)Floyd–Steinberg 抖动这样的东西,事情变得复杂得多,因为一个输出像素取决于所有先前的输出像素(除了输入像素)。在这种情况下,您可以将“3 色”位图拆分为三个单独的单色位图(每个处理器一个,最多 3 个处理器)并且每个处理器可以抖动其单色位图,然后您可以将三个生成的单色位图合并在一起获得单个“3 色”输出位图;但实际上不可能使用超过 3 个处理器(不更改为更适合并行化的不同抖动算法)。

画一个圆或者一个椭圆,你可以让每个处理器画一条弧线,然后组合弧线;要绘制 1234 个形状,您可以将图像拆分为一个网格,并让每个处理器在网格内进行拼贴。