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