0

我将如何将位图划分为段并用于并行处理?我已经有了位图的高度和宽度,但是从这里开始。我读过使用MPI_Cart_shift()and 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)
4

1 回答 1

1

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

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

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

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

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

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

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

为了绘制一个圆或一个椭圆,您可以让每个处理器绘制一条弧并组合这些弧;对于绘制 1234 个形状,您可以将图像分割成一个网格,并让每个处理器在网格内做一个平铺。

于 2018-09-17T09:00:35.687 回答