parfor
— это удобный способ распределить независимые итерации интенсивных вычислений между несколькими «воркерами». Одно существенное ограничение заключается в том, что parfor
-циклы не могут быть вложены, и неизменно это ответ на подобные вопросы, такие как там и там .
Почему так желательно распараллеливание через границы цикла
Рассмотрим следующий фрагмент кода, в котором итерации занимают сильно различающееся количество времени на машине, которая поддерживает 4 рабочих процесса. Оба цикла перебирают 6 значений, которые явно трудно разделить между 4.
for row = 1:6
parfor col = 1:6
somefun(row, col);
end
end
Кажется хорошей идеей выбрать внутренний цикл для parfor
, потому что отдельные вызовы somefun
более изменчивы, чем итерации внешнего цикла. Но что, если время выполнения каждого вызова somefun
очень похоже? Что, если есть тенденции во времени выполнения, и у нас есть три вложенных цикла? Эти вопросы возникают регулярно, и люди переходят к крайности.
Для объединения циклов требуется шаблон
В идеале somefun
выполняется для всех пар row
и col
, и рабочие должны быть заняты независимо от того, какой iterand изменяется. Решение должно выглядеть так
parfor p = allpairs(1:6, 1:6)
somefun(p(1), p(2));
end
К сожалению, даже если бы я знал, какая встроенная функция создает матрицу со всеми комбинациями row
и col
, MATLAB выдал бы ошибку Диапазон оператора parfor должен быть вектором-строкой. Тем не менее, for
не будет жаловаться и хорошо перебирать столбцы. Простым обходным решением было бы создать эту матрицу, а затем проиндексировать ее с помощью parfor
:
p = allpairs(1:6, 1:6);
parfor k = 1:size(pairs, 2)
row = p(k, 1);
col = p(k, 2);
somefun(row, col);
end
Что такое встроенная функция вместо allpairs
, которую я ищу? Есть ли удобный идиоматический шаблон, который кто-то придумал?