parfor
A parfor
-цикл в MATLAB® выполняет последовательность операторов в теле цикла параллельно. Клиент MATLAB выдает parfor
команда и координирует с работниками MATLAB выполнение итераций цикла параллельно для работников в параллельном пуле. Клиент отправляет необходимые данные, по которым parfor
работает с рабочими, где выполняется большая часть расчетов. Результаты отправляются обратно клиенту и собираются.
A parfor
-цикл может обеспечить значительно лучшую эффективность, чем его аналогичный for
-loop, потому что несколько работники MATLAB могут вычислять одновременно в одном цикле.
Каждое выполнение тела parfor
-цикл - это iteration. Работники MATLAB оценивают итерации не в определенном порядке и независимо друг от друга. Поскольку каждая итерация является независимой, нет гарантии, что итерации никоим образом синхронизируются, и в этом нет необходимости. Если количество рабочих процессов равно количеству итераций цикла, каждый рабочий процесс выполняет одну итерацию цикла. Если итераций больше, чем рабочих, некоторые рабочие люди выполняют более одной итерации цикла; в этом случае рабочий процесс может получить несколько итераций сразу, чтобы уменьшить время связи.
A parfor
-цикл может быть полезен, если у вас медленно for
-цикл. Рассмотрим parfor
если у вас есть:
Некоторые итерации цикла, выполнение которых занимает много времени. В этом случае рабочие могут выполнять длинные итерации одновременно. Убедитесь, что количество итераций превышает количество рабочих. В противном случае вы не будете использовать все доступные работники.
Многие итерации цикла простого вычисления, такие как симуляция Монте-Карло или свип параметра. parfor
разделяет итерации цикла на группы, так что каждый рабочий процесс выполняет некоторые фрагменты от общего количества итераций.
A parfor
-цикл может не пригодиться, если у вас есть:
Код, который векторизировал for
-циклы. Обычно, если вы хотите заставить код запускаться быстрее, сначала попробуйте векторизировать его. Для получения дополнительной информации об этом см. Раздел «Векторизация». Векторизация кода позволяет вам воспользоваться встроенным параллелизмом, обеспечиваемым многопоточным характером многих базовых библиотек MATLAB. Однако, если у вас есть векторизованный код и у вас есть доступ только к локальным работникам, то parfor
-циклы могут работать медленнее, чем for
-циклы. Не отклоняйте код, чтобы разрешить parfor
; в целом это решение работает плохо.
Итерации цикла, выполнение которых занимает короткое время. В этом случае в вычислении доминируют параллельные накладные расходы.
Вы не можете использовать parfor
-loop, когда итерация в вашем цикле зависит от результатов других итераций. Каждая итерация должна быть независимой от всех других. Для получения помощи в работе с независимыми циклами см. «Убедитесь, что итерации цикл parfor являются независимыми». Исключением из этого правила является накопление значений в цикле с помощью переменных сокращения.
В решении, когда использовать parfor
, рассмотрите параллельные накладные расходы. Параллельные накладные расходы включают время, необходимое для связи, координации и передачи данных - отправки и приема данных - от клиента к работникам и обратно. Если итерационные вычисления выполняются быстро, эти накладные расходы могут составлять значительную часть общего времени. Рассмотрим два разных типа итераций цикла:
for
-циклы с вычислительно сложной задачей. Эти циклы, как правило, являются хорошими кандидатами для преобразования в parfor
-цикл, потому что время, необходимое для расчетов, доминирует во времени, необходимом для передачи данных.
for
-циклы с простой вычислительной задачей. Эти циклы обычно не выигрывают от преобразования в parfor
-цикл, потому что время, необходимое для передачи данных, является значительным по сравнению со временем, необходимым для расчетов.
parfor
С низкими параллельными накладными расходамиВ этом примере вы начинаете с вычислительно сложной задачи внутри for
-цикл. for
-циклы медленные, и вы ускоряете вычисление с помощью parfor
-циклы вместо этого. parfor
разделяет выполнение for
-итерации цикла над рабочими в параллельном пуле.
Этот пример вычисляет спектральный радиус матрицы и преобразует for
-цикл в a parfor
-цикл. Узнайте, как измерить полученное ускорение и сколько данных переносится в и от работников в параллельном пуле.
В редакторе MATLAB введите следующее for
-цикл. Добавить tic
и toc
для измерения времени расчета.
tic n = 200; A = 500; a = zeros(n); for i = 1:n a(i) = max(abs(eig(rand(A)))); end toc
Запустите скрипт и отметьте прошедшее время.
Elapsed time is 31.935373 seconds.
В скрипте замените for
-цикл с a parfor
-цикл. Добавить ticBytes
и tocBytes
для измерения объема данных, передаваемых работникам параллельного пула.
tic ticBytes(gcp); n = 200; A = 500; a = zeros(n); parfor i = 1:n a(i) = max(abs(eig(rand(A)))); end tocBytes(gcp) toc
Запустите новый скрипт на четырех рабочих местах и еще раз. Обратите внимание, что первый запуск медленнее, чем второй запуск, поскольку параллельный пул занимает некоторое время, чтобы запустить и сделать код доступным для работников. Обратите внимание на передачу данных и истекшее время для второго запуска.
По умолчанию MATLAB автоматически открывает параллельный пул работников на локальной машине.
Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers. ... BytesSentToWorkers BytesReceivedFromWorkers __________________ ________________________ 1 15340 7024 2 13328 5712 3 13328 5704 4 13328 5728 Total 55324 24168 Elapsed time is 10.760068 seconds.
parfor
пробежать на четырех рабочих примерно в три раза быстрее, чем соответствующий for
-цикл вычисление. Ускорение меньше, чем идеальное ускорение коэффициента четыре на четырех рабочих. Это связано с параллельными накладными расходами, включая время, необходимое для передачи данных от клиента работникам и обратно. Используйте ticBytes
и tocBytes
результаты для изучения объема переданных данных. Предположим, что время, необходимое для передачи данных, пропорционально размеру данных. Это приближение позволяет вам получить указание времени, необходимого для передачи данных, и сравнить ваши параллельные накладные расходы с другими parfor
-итерации цикла. В этом примере передача данных и параллельные накладные расходы малы по сравнению со следующим примером.Текущий пример имеет низкие параллельные накладные расходы и выгоды от преобразования в parfor
-цикл. Сравните этот пример с простыми итерациями цикла в следующем примере, см. Пример parfor с высокими параллельными накладными расходами.
Для другого примера parfor
-цикл с вычислительно сложными задачами, см. Вложенный parfor и for-Loops и Другие требования parfor
parfor
С высокими параллельными накладными расходамиВ этом примере вы записываете цикл, чтобы создать простую синусоиду. Замена for
-цикл с a parfor
-цикл не ускоряет вычисление. Этот цикл не имеет большого количества итераций, он не занимает много времени, и вы не замечаете увеличения скорости выполнения. Этот пример имеет высокие параллельные накладные расходы и не выигрывает от преобразования в parfor
-цикл.
Запишите цикл, чтобы создать синусоиду. Использовать tic
и toc
для измерения истекшего времени.
tic n = 1024; A = zeros(n); for i = 1:n A(i,:) = (1:n) .* sin(i*2*pi/1024); end toc
Elapsed time is 0.012501 seconds.
Замените for
-цикл с a parfor
-цикл. Добавить ticBytes
и tocBytes
для измерения объема данных, передаваемых работникам параллельного пула.
tic ticBytes(gcp); n = 1024; A = zeros(n); parfor (i = 1:n) A(i,:) = (1:n) .* sin(i*2*pi/1024); end tocBytes(gcp) toc
Запустите скрипт на четырех рабочих местах и снова запустите код. Обратите внимание, что первый запуск медленнее, чем второй запуск, поскольку параллельный пул занимает некоторое время, чтобы запустить и сделать код доступным для работников. Обратите внимание на передачу данных и истекшее время для второго запуска.
BytesSentToWorkers BytesReceivedFromWorkers __________________ ________________________ 1 13176 2.0615e+06 2 15188 2.0874e+06 3 13176 2.4056e+06 4 13176 1.8567e+06 Total 54716 8.4112e+06 Elapsed time is 0.743855 seconds.
for
-цикл, чем для parfor
-задать на четырех рабочих. В этом случае вы не выигрываете от поворота for
-цикл в parfor
-цикл. Причина состоит в том, что передача данных намного больше, чем в предыдущем примере, см. Пример parfor с низкими параллельными накладными расходами. В текущем примере параллельные накладные расходы доминируют во времени вычисления. Поэтому итерация синусоиды не выигрывает от преобразования в parfor
-цикл.Этот пример иллюстрирует, почему вычисления высоких параллельных накладных расходов не выигрывают от преобразования в parfor
-цикл. Дополнительные сведения о ускорении кода см. в разделе Преобразование циклов for-Loops в циклы parfor