如何将嵌套循环转换为parfor循环

时间:2016-01-19 11:10:19

标签: performance matlab gpu vectorization bsxfun

这是我的MATLAB脚本。

function [ Im ] = findBorders( I )


Im = false(size(I));

I = padarray(I, [1, 1], 1);
[h w] = size(Im);

bkgFound = false;
for row = 1 : h
    for col = 1 : w
        if I(row + 1, col + 1)

            bkgFound = false;
            for i = 0:2
                for j = 0:2
                    if ~I(row + i, col + j)
                        Im(row, col) = 1;
                        bkgFound = true;
                        break;
                    end;
                end;

                if bkgFound
                    break;
                end;
            end;
        end;
    end;
end;

所以,我需要将其转换为parfor循环,以运行GPU。

我需要帮助。我读了一些文章,但不知道如何转换它。

1 个答案:

答案 0 :(得分:3)

在MATLAB中,parfor不允许在GPU上运行。通过MATLAB与GPU连接的最佳方法是将数据转换为gpuArray,然后对那些针对GPU优化的数据执行的所有操作都将在那里进行优化。

正如@Daniel所说,您发布的代码1)不适合任何类型的并行处理,2)可能只能通过矢量化来加速。

我不完全确定你要做的是什么,但似乎你正试图在图像中找到被" not-background&#34包围的像素;。为此,我通常会使用2D卷积和邻域内核来计算出一个像素给定值的邻居数。

例如,以下代码查找任何本身为false且完全被false值包围的像素(假设您的输入图像为logical

I = [...
    1 1 1 1 0;
    1 0 0 0 0;
    0 0 0 0 0;
    0 0 0 0 0;
    0 0 0 1 1;
    0 0 0 1 0;
];

surrounded_by_zeros = conv2(double(I), ones(3), 'same') == 0

surrounded_by_zeros =

    0 0 0 0 0
    0 0 0 0 0
    0 0 1 1 1
    1 1 0 0 0
    1 1 0 0 0
    1 1 0 0 0

我个人喜欢这个解决方案,但如果你有图像处理工具箱,你也可以使用imerodeimdilate基本上做同样的事情。

surrounded_by_zeros = ~imdilate(I, ones(3));
surrounded_by_zeros = imerode(~I, ones(3));

如果由于某种原因你真的需要将这个计算移到GPU上(你不是),你可以将它转换为gpuArray,然后执行相同的操作,它将使用GPU背后场景

I = gpuArray(I);
surrounded_by_zeros_on_gpu = conv2(double(I), ones(3), 'same') == 0;

请记住,这会将I复制到GPU上,这对于足够大的图像来说可能是一个重大的性能损失。