0

我在 Matlab 中编写了一些图像处理代码,我想使用并行处理来加快速度。我选择了耗时最长的任务:对图像应用高斯模糊。在文件交换的帮助下,我已经获得了比 imfilter() 更快的高斯模糊。但是,它仍然不会扩大规模。这是我的测试代码:

clear all
clc
image_paths = dir('C:\pics\Baustahl\3Bleche(3)\*.png');       
image_paths = sort({image_paths.name});

count = 600;

Img = cell(1, count);
Mean = cell(1, count);

for i = 1:count
    Img{i} = imread(['C:\pics\Baustahl\3Bleche(3)\ ' image_paths{i}]);
    Img{i} = Img{i}(:,:,1);
    Img{i} = single(Img{i})./255;
end
clear vars bilder

fprintf(1, 'Starting processing....\n');

starttime = tic;
parfor (i = 1:count, 4)
    Mean{i} = imgaussian(Img{i}, 25, 81);
end
elapsedtime = toc(starttime);
fprintf(1, 'Finished processing. (%d Files in %.1fs, %.1f files/second)\n', count, elapsedtime, count/elapsedtime);
fprintf(1, '\n');

clear vars Img Mean

我的系统有 Q6600 和 4GB 的 RAM(足够了),如果我将 MATLAB 限制为一个内核,我会得到:

加工完毕。(12.0s 600 个文件,49.8 个文件/秒)

两个核心:

加工完毕。(7.5s 600 个文件,80.3 个文件/秒)

使用所有四个核心,我得到以下信息:

加工完毕。(5.7 秒内 600 个文件,104.7 个文件/秒)

尽管性能应该翻两番,但速度提高了两倍。每次迭代都独立于其他迭代,因此这非常适合并行处理。为什么它的规模如此之大?

我尝试过的事情:

  1. 我为 C# 安装了 OpenCV 和 EmguCV 包装器。使用标准 for 循环,我每秒得到 ~52 个文件,使用 Parallel.ForEach() 我得到 ~200 个文件/秒。(正如我所料)
  2. 使用不同数量的文件。如果我选择足够的文件,则不会更改文件/秒:

    0.3s 20 个文件,72.7 个文件/秒
    0.6s 60 个文件,94.3 个文件/秒
    1.9s 200 个文件,105.3 个文件/秒

  3. 在 Matlab 中使用普通的 for 循环不会改变任何事情。显然,它与 parfor-loop 执行相同数量的并行化(自动魔术)。

  4. 明确指定它应该使用 4 个工作线程(见上文) - 什么都不做。(设置为 1 时甚至不会降低性能)

这些文件大约是。640x480 灰度,内容相似。

有什么想法吗?

4

2 回答 2

0

您是否打开了matlabpool调用前的parfor功能(否则它会像正常的一样)?

matlabpool 4
parfor 
    ...
end
matlabpool close

请注意,打开和关闭池将有 10-20 秒的开销。

于 2013-05-10T16:14:56.883 回答
0

从您的代码中添加一个简单的内容,这是一个相当不错的加速。如上所述,parfor如果您没有足够的迭代或计算,实际上可能会损害性能。将文件发送到正确的内存空间并将其带回的开销可能会导致这种情况。

我想您可以尝试spmd将每个工人的图像数量平均分配(有点像parfor无论如何)。真的不确定何时可以使用spmd或是否更快,但值得一试。parforparfor

于 2013-05-11T08:32:41.897 回答