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: Я запускаю код на четырехъядерном процессоре, поэтому ожидаю увидеть некоторые улучшения.


person Junier    schedule 04.07.2010    source источник
comment
не могли бы вы сообщить нам значения numdims, numcases и фактические значения времени, которые вы нашли? Благодарю.   -  person rwong    schedule 04.07.2010


Ответы (3)


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

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

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

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

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

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

person jdehaan    schedule 04.07.2010
comment
Однако спасибо за ответ на странице mathworks.com/access/helpdesk В /help/toolbox/distcomp/parfor.html говорится, что parfor будет значительно быстрее, чем соответствующий оператор for, даже если n относительно мало. (Конечно, я не понимаю, что означает относительно небольшой размер.) Я смущен, но что вы подразумеваете под накладными расходами при разделении работы и сборе результатов из нескольких потоков / ядер? Переменные A и данные являются глобальными и уже должны использоваться всеми потоками. Все, что нужно сделать Matlab, - это осторожно добавлять в bistar. - person Junier; 04.07.2010
comment
Я добавил точность, спасибо за ссылку. Я просмотрел справку, и в ней указано то же, что я пытаюсь прояснить. Я не очень хорош в объяснении :-) Часть предложения if очень важна. Надеюсь, это поможет! Это верно не только для Matlab, но и для всех видов параллельных вычислений. Важно правильно разделить проблему. - person jdehaan; 04.07.2010
comment
+1 за указание на необходимость прочитать всю справку, а не только ту часть, которая, кажется, говорит то, что вы хотите. - person Donnie; 04.07.2010
comment
Еще раз спасибо, jdehaan :) Забавно, я думаю, что MATLAB на самом деле создает 4 процесса, и я предполагаю, что эти процессы передаются на аутсорсинг, поэтому накладные расходы, о которых вы говорите, ощущаются (поскольку между процессами нет общей памяти). Однако в идеальном мире работа была бы передана на аутсорсинг потокам, которые разделяют переменные A, data и bistar, поэтому разделение будет вопросом передачи индексов (незначительные накладные расходы), а поскольку bistar является общим, рекомбинация - это просто вопрос добавления к правильные индексы параллельно (незначительные накладные расходы). Разве это не было бы быстрее? Я что-то упускаю? - person Junier; 05.07.2010
comment
@Donnie Я не проглядел нарочно, я устал от работы и буквально собирался лечь спать ... - person Junier; 05.07.2010
comment
@Junier: Помещение рабочих процессов в потоки вместо процессов ускорит доступ к памяти, но PCT предназначен для масштабирования для распределения между рабочими на нескольких серверах в вычислительной ферме, у которой не будет общей памяти или даже той же архитектуры. Кроме того, это было бы сложно: Matlab (язык, а не виртуальная машина) является однопоточным, поэтому некоторый код, который вы можете вызвать, включая MEX-файлы или библиотеки на основе C, Java или внутренние компоненты Matlab, не является реентерабельным и может выйти из строя при одновременном вызове. - person Andrew Janke; 06.07.2010
comment
Тем не менее, более новые версии Matlab автоматически используют многопоточность в некоторых встроенных функциях, таких как sum () и * (умножение матриц). Ваш код может уже использовать преимущества нескольких ядер, и чем больше он векторизован, тем больше Matlab сможет его многопоточно. Именно так Matlab обычно выполняет многоядерные операции для более простых операций с наборами данных, которые могут уместиться в одном процессе. См. mathworks.com/support/solutions/ ru / data / 1-4PG4AN / - person Andrew Janke; 06.07.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.

person Jonas    schedule 04.07.2010

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

person Daniel    schedule 06.02.2016