2013-05-10 3 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 и 4 Гб оперативной памяти (что достаточно), и если ограничить MATLAB для одного ядра я получаю:

Готовой обработку. (600 файлов в 12.0s, 49,8 файлы/сек)

Два ядра:

завершенности обработки. (600 файлов в 7.5s, 80,3 файлы/сек)

Используя все четыре ядра, я получаю следующее:

завершенности обработки. (600 файлов в 5.7s, 104.7 файлов в секунду)

Это ускорение на два, хотя производительность должна быть вчетверо. Каждая итерация не зависит от других, поэтому это действительно хорошо подходит для параллельной обработки. Почему это так плохо?

вещи я попытался:

  1. Я установил OpenCV и EmguCV обертку для C#. Используя стандартный цикл for, я получаю ~ 52 файла в секунду, используя Parallel.ForEach(), я получаю ~ 200 файлов в секунду. (Как я ожидал)
  2. Использование различного количества файлов. Не изменяет файлы/второй, если выбрать достаточное количество файлов:

    20 Файлы в 0.3s, 72,7 файлы/второй
    60 Файлы в 0.6s, 94,3 файлов/сек
    200 Файлы в 1.9s, 105.3 файлы/сек.

  3. Использование нормального цикла в Matlab ничего не меняет. По-видимому, он делает такое же количество распараллеливаний (автоматически-магически), как парр-петля.

  4. Явно указать, что он должен использовать 4 рабочих потока (см. Выше) - ничего не делает. (Даже не ухудшать характеристики при установке на 1)

Файлы прибл. 640x480 оттенки серого и имеют аналогичное содержимое.

Любые мысли?

ответ

0

Вы открыли matlabpool перед вызовом parfor (иначе он будет вести себя как нормальный для)?

matlabpool 4 
parfor 
    ... 
end 
matlabpool close 

Имейте в виду, что для открытия и закрытия бассейна должно быть 10-20 секунд накладных расходов.

+0

Я только что попробовал (за исключением вызовов matlabpool от времени, конечно), и он получает _slower_ до 56 кадров в секунду. –

0

Это довольно хорошее ускорение от простого дополнения к вашему коду. Как упоминалось выше, на самом деле могут быть отрицательные характеристики, используя parfor, если у вас нет достаточного количества итераций или вычислений. Накладные расходы на отправку файлов в нужное пространство памяти и их возврат могут привести к этому.

Я думаю, вы могли бы попробовать spmd и одинаково разделить количество изображений для каждого рабочего (вроде как то, что parfor все равно). На самом деле не уверен, что spmd или parfor быстрее, если вы можете использовать parfor, но его стоит того.