код, с которым я имею дело, имеет циклы как следующее:
bistar = zeros(numdims,numcases);
parfor hh=1:nt
bistar = bistar + A(:,:,hh)*data(:,:,hh+1)' ;
end
для маленького nt (10).
После синхронизации его он на самом деле в 100 раз медленнее, чем использование регулярного цикла!!! Я знаю, что parfor может сделать параллельные суммы, таким образом, я не уверен, почему это не работает.
Я работаю
matlabpool
с out-of-the-box конфигурациями прежде, чем выполнить мой код.
Я относительно плохо знаком с matlab и только что начал использовать параллельные функции, поэтому не предполагайте, что я, не делаю чего-то глупого.
Спасибо!
PS: я выполняю код четырехъядерного, таким образом, я ожидал бы видеть некоторые улучшения.
Выполнение разбиения и группировки результатов (накладные расходы на разделение работы и сбор результатов от нескольких потоков/ядер) высоки для малых значений 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 мс с для
, 132 мс с parfor
). Если бы вы выполняли только 10 итераций, parfor
был бы медленнее (50 мс с для
, 112 мс с parfor
).
Вы можете рассчитать накладные расходы на своей машине, сравнив время выполнения с 1 рабочим и 0 рабочих, и вы можете оценить прирост скорости, подгоняя лайнер во время выполнения от 1 до 4 рабочих. Тогда вы узнаете, когда будет полезно использовать parfor
.