2013-05-10 61 views
0

我已经在Matlab中编写了一些图像处理代码我想加快使用并行处理。我选择了花费时间最长的任务:将高斯模糊应用于图像。在文件交换的帮助下,我已经比imfilter()获得了更快的高斯模糊。但是,它仍然不会放大。这里是我的测试代码:使用parfor正确并行化

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一个核心,我得到:

成品加工。 (600个文件中12.0S,49.8文件/秒)

两个核心:

完成处理。 (600个文件中7.5S,80.3文件/秒)

使用所有四个核心,我得到以下几点:

成品加工。 (600个5.7s文件,104.7个文件/秒)

这是一个加速两倍,但性能应该四倍。每次迭代都独立于其他,因此这非常适合并行处理。 它为什么如此糟糕?

事情我已经尝试:

  1. 我安装的OpenCV和EmguCV包装为C#。使用标准的for-loop我使用Parallel.ForEach()获得〜52个文件/秒,我得到〜200个文件/秒。 (如我所料)
  2. 使用不同数量的文件。不改变文件/秒,如果我选择足够的文件:

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

  3. 在Matlab中使用正常for-loop不会改变任何内容。显然,它和parfor-loop做了相同数量的并行(自动神奇地)。

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

这些文件大约是。 640x480灰度并具有相似的内容。

有什么想法?

回答

0

打电话给parfor之前是否打开过matlabpool(否则它的行为将与正常行为相同)?

matlabpool 4 
parfor 
    ... 
end 
matlabpool close 

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

+0

我刚刚尝试过(不包括来自课程时间的matlabpool调用),它获得_lowlow_大约56 fps。 – 2013-05-10 16:21:21

0

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

我想你可以试试spmd,同样划分每个工作者的图片数量(类似于parfor所做的那样)。真的不知道如果spmdparfor是更快,当你可以使用parfor但它值得一试。