exponenta event banner

Решить, когда использовать parfor

parfor-Loops в MATLAB

A parfor-loop в MATLAB ® выполняет ряд инструкций в теле цикла параллельно. Клиент MATLAB выдает parfor и координирует с работниками MATLAB выполнение итераций цикла параллельно на работниках в параллельном пуле. Клиент отправляет необходимые данные, parfor работает с работниками, где выполняется большая часть вычислений. Результаты отправляются обратно клиенту и собираются.

A parfor-loop может обеспечить значительно лучшую производительность, чем его аналогичный for-loop, поскольку несколько работников MATLAB могут вычисляться одновременно в одном цикле.

Каждое выполнение тела parfor-loop является итерацией. Работники MATLAB оценивают итерации не в определенном порядке и независимо друг от друга. Поскольку каждая итерация независима, нет гарантии, что итерации каким-либо образом синхронизированы, и нет необходимости в этом. Если число работников равно числу итераций цикла, каждый работник выполняет одну итерацию цикла. Если итераций больше, чем рабочих, некоторые рабочие выполняют более одной итерации цикла; в этом случае работник может принимать сразу несколько итераций, чтобы сократить время связи.

Решение о том, когда использовать Parfor

A parfor-loop может быть полезен, если у вас медленный for-луп. Рассмотреть parfor при наличии:

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

  • Множество итераций цикла простого вычисления, например моделирование Монте-Карло или протягивание параметров. parfor разделяет итерации цикла на группы, так что каждый работник выполняет некоторую часть общего числа итераций.

A parfor-loop может оказаться нецелесообразным, если имеется:

  • Код, который векторизировал for-контуры. Как правило, если требуется ускорить выполнение кода, сначала попробуйте выполнить его векторизацию. Дополнительные сведения об этом см. в разделе Векторизация. Код векторизации позволяет воспользоваться преимуществами встроенного параллелизма, обеспечиваемого многопоточностью многих базовых библиотек MATLAB. Однако если у вас есть векторизированный код и у вас есть доступ только к местным работникам, то parfor-циклы могут выполняться медленнее, чем for-контуры. Не удалять код для разрешения parfor; в целом это решение работает плохо.

  • Итерации цикла, выполнение которых занимает короткое время. В этом случае в расчете доминируют параллельные накладные расходы.

Нельзя использовать parfor- петля, когда итерация в цикле зависит от результатов других итераций. Каждая итерация должна быть независимой от всех остальных. Для получения справки по работе с независимыми циклами см. раздел Обеспечение независимости итераций parfor-Loop. Исключением из этого правила является накопление значений в цикле с использованием переменных сокращения.

При принятии решения о том, когда использовать parfor, рассмотрим параллельные накладные расходы. Параллельные накладные расходы включают время, необходимое для связи, координации и передачи данных - отправки и получения данных - от клиента к работникам и обратно. Если итерационные оценки выполняются быстро, эти накладные расходы могут составлять значительную часть общего времени. Рассмотрим два различных типа итераций цикла:

  • for- петли с вычислительно требовательной задачей. Эти петли, как правило, являются хорошими кандидатами для преобразования в parfor-контур, поскольку время, необходимое для вычислений, доминирует над временем, требуемым для передачи данных.

  • for- циклы с простой вычислительной задачей. Эти петли, как правило, не выигрывают от преобразования в parfor-контур, поскольку время, необходимое для передачи данных, значительно по сравнению со временем, необходимым для вычислений.

Пример parfor С низкими параллельными накладными расходами

В этом примере вы начинаете с вычислительно требовательной задачи внутри for-луп. for- циклы медленные, и вы ускоряете расчет с помощью parfor-закольцовывает вместо этого. parfor разделяет выполнение for-итерации петель над рабочими в параллельном пуле.

В этом примере вычисляется спектральный радиус матрицы и преобразуется for-закольцовывание в parfor-луп. Узнайте, как измерить результирующее ускорение и какой объем данных передается работникам и от них в параллельном пуле.

  1. В редакторе 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
  2. Запустите сценарий и запишите истекшее время.

    Elapsed time is 31.935373 seconds.

  3. В сценарии замените for-закольцовывание с помощью 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

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

    По умолчанию 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 With High Parallel Health.

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

Пример parfor С высокими параллельными накладными расходами

В этом примере создается цикл для создания простой синусоидальной волны. Замена for-закольцовывание с помощью parfor-loop не ускоряет вычисление. Этот цикл не имеет много итераций, он не занимает много времени для выполнения и вы не замечаете увеличения скорости выполнения. Этот пример имеет высокий уровень параллельных служебных данных и не получает преимуществ от преобразования в parfor-луп.

  1. Запишите цикл для создания синусоидальной волны. Использовать 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.
  2. Замените for-закольцовывание с помощью 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

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

                 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-loop, чем для parfor-закольцовывание на четырех рабочих. В этом случае вы не выиграете от поворота for-закольцовывание в parfor-луп. Причина заключается в том, что перенос данных намного больше, чем в предыдущем примере, см. Пример parfor With Low Parallel Supply. В текущем примере параллельные служебные данные доминируют над вычислительным временем. Поэтому итерация синусоидальной волны не получает преимуществ от преобразования в parfor-луп.

Этот пример иллюстрирует, почему высокие параллельные расчеты накладных расходов не выигрывают от преобразования в parfor-луп. Дополнительные сведения об ускорении кода см. в разделе Преобразование циклов for-Loops в циклы parfor-Loops

См. также

| |

Связанные темы