MATLAB Parfor медленнее, чем для - что не так? - PullRequest
17 голосов
/ 04 июля 2010

код, с которым я имею дело, имеет циклы, подобные следующему:

bistar = zeros(numdims,numcases); 
parfor hh=1:nt       
  bistar = bistar +  A(:,:,hh)*data(:,:,hh+1)' ;
end   

для маленьких nt (10).

После синхронизации, это на самом деле 100 раз медленнее , чем при использовании обычного цикла !!! Я знаю, что parfor может делать параллельные суммы, поэтому я не уверен, почему это не работает.

Я бегу

matlabpool

с готовыми конфигурациями перед запуском моего кода.

Я относительно новичок в Matlab и только начал использовать параллельные функции, поэтому, пожалуйста, не думайте, что я не делаю глупостей.

Спасибо!

PS: я запускаю код на четырехъядерном ядре, поэтому я ожидаю увидеть некоторые улучшения.

Ответы [ 3 ]

22 голосов
/ 04 июля 2010

Выполнение разделения и группировки результатов (накладные расходы на разделение работы и сбор результатов из нескольких потоков / ядер) велико для небольших значений nt. Это нормально, вы не разбиваете данные на простые задачи, которые можно быстро выполнить простым циклом.

Всегда выполняйте что-то сложное внутри цикла, которое стоит затрат на разделение. Вот хорошее введение в параллельное программирование .

Потоки происходят из пула потоков, поэтому накладные расходы на создание потоков не должны быть там. Но для создания частичных результатов n матрицы из размера bistar должны быть созданы, все частичные результаты вычислены, а затем должны быть добавлены все эти частичные результаты (рекомбинация). В прямом цикле это с высокой вероятностью выполняется на месте, распределения не производятся.

Полный текст справки (спасибо за ссылку ниже):

Если время для вычисления f, g и h равно большой , парфор будет значительно быстрее, чем соответствующий для утверждение, даже если п относительно маленький.

Итак, вы видите, что они имеют в виду то же, что и я, накладные расходы для малых значений n стоят усилий, только если то, что вы делаете в цикле, достаточно сложно / требует много времени.

13 голосов
/ 04 июля 2010

Parfor идет с небольшим количеством накладных расходов.Таким образом, если nt действительно мало, и если вычисления в цикле выполняются очень быстро (как сложение), решение parfor медленнее.Кроме того, если вы запускаете parfor на четырехъядерном процессоре, прирост скорости будет близок к линейному для 1-3 ядер, но меньше, если вы используете 4 ядра, поскольку последнее ядро ​​также должно запускать системные процессы.

Например, если parfor идет с накладными расходами 100 мс, а вычисления в цикле занимают 5 мс, и если мы предположим, что выигрыш в скорости линейен до 4 ядер с коэффициентом 1 (т.е. использование 4 ядер делает вычисление 4 разабыстрее), nt должно быть около 30, чтобы вы могли получить прирост скорости с parfor (150 мс с for, 132 мс с parfor).Если бы вы выполняли только 10 итераций, parfor был бы медленнее (50 мс с for, 112 мс с parfor).

Вы можете рассчитать накладные расходы на вашей машине, сравнив время выполнения с 1 рабочимпротив 0 работников, и вы можете оценить выигрыш в скорости, подгоняя лайнер по времени выполнения с 1 до 4 работниками.Тогда вы узнаете, когда полезно использовать parfor.

3 голосов
/ 06 февраля 2016

Помимо плохой производительности из-за коммуникационных издержек (см. Другие ответы), есть и другая причина не использовать parfor в этом случае.Все, что делается в parfor, в этом случае использует встроенную многопоточность .Если предположить, что все работники работают на одном и том же ПК, это не дает никаких преимуществ, поскольку один вызов уже использует все ядра вашего процессора.

...