MATLAB parfor медленнее, чем для - что не так?
код, с которым я имею дело, имеет следующие петли:
bistar = zeros(numdims,numcases);
parfor hh=1:nt
bistar = bistar + A(:,:,hh)*data(:,:,hh+1)' ;
end
для малых nt (10).
После определения времени, это на самом деле в 100 раз медленнее, чем при использовании регулярного цикла!!! Я знаю, что parfor может делать параллельные суммы, поэтому я не уверен, почему это не работает.
Я запустил
matlabpool
с готовыми конфигурациями перед запуском моего кода.
Я относительно новичок в Matlab и просто начал использовать параллельные функции, поэтому, пожалуйста, не предполагайте, что я не делаю что-то глупое.
Спасибо!
PS: Я запускаю код на четырехъядерном ядре, поэтому я ожидаю увидеть некоторые улучшения.
Ответы
Ответ 1
Выполнение разбиения на разделы и группировка результатов (накладные расходы при разделении результатов работы и сбора из нескольких потоков/ядер) высока для небольших значений nt
. Это нормально, вы не будете разделять данные для выполнения простых задач, которые могут выполняться быстро в простейшем цикле.
Всегда выполняйте что-то сложное внутри цикла, которое стоит затрат на разбиение. Вот хороший введение в параллельное программирование.
Потоки поступают из пула потоков, поэтому накладные расходы на создание потоков не должны быть там. Но для создания частичных результатов должны быть созданы матрицы n
из размера bistar
, все частичные результаты вычислены, а затем все эти частичные результаты должны быть добавлены (рекомбинированы). В прямом цикле это с большой вероятностью выполняется на месте, никаких распределений не происходит.
Полное выражение в справочной системе (спасибо за вашу ссылку):
Если время вычисления f, g и h равно большой, parfor будет значительно быстрее, чем соответствующее для утверждение, даже если n относительно мало.
Итак, вы видите, что они имеют в виду то же самое, что и я имею в виду, накладные расходы для небольших значений n стоит только усилий, если то, что вы делаете в цикле, является достаточно сложным/трудоемким.
Ответ 2
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
Помимо плохой производительности из-за служебных данных связи (см. другие ответы), в этом случае есть еще одна причина не использовать parfor
. Все, что сделано в parfor
, в этом случае использует встроенную многопоточность. Предполагая, что все рабочие работают на одном ПК, нет никакого преимущества, потому что один звонок уже использует все ядра вашего процессора.