Ускорение for-Цикл реализации в коде, сгенерированная при помощи parfor

Когда вы генерируете код C/C + + для модели при помощи блока MATLAB Function, MATLAB System, и For Each подсистемы, по умолчанию генератор кода производит код, который реализует for- циклы в одном потоке. Этот for-цикл может быть оптимизирован для блоков MATLAB Function и MATLAB System. Итерации parfor-цикл может работать параллельно на нескольких ядрах на целевом компьютере.

Параллельный запуск итераций может значительно улучшить скорость выполнения сгенерированного кода. Для получения дополнительной информации смотрите Как циклы parfor Улучшить Скорость выполнения.

Генератор кода реализует for-циклы параллельно при помощи OpenMP.

Программное обеспечение Embedded Coder™ использует прикладной интерфейс Open Multiprocessing (OpenMP) для поддержки генерации кода с общей памятью и многоядерными процессорами. По умолчанию Embedded Coder использует столько потоков, сколько найдет доступным. Если вы задаете количество потоков для использования, Embedded Coder использует самое большее количество потоков, даже если доступны дополнительные потоки. Для получения дополнительной информации см. parfor.

Как циклы parfor улучшают скорость выполнения

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

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

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

Когда использовать циклы parfor

Использовать parfor когда у вас есть:

  • Многие итерации простого вычисления. parfor разделяет итерации цикла на группы, так что каждый поток выполняет одну группу итераций.

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

Когда не использовать циклы parfor

Не используйте parfor когда:

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

    Чтобы помочь вам избежать использования parfor когда итерация вашего цикла зависит от других итераций, Embedded Coder задает жесткую классификацию переменных. Для получения дополнительной информации смотрите Классификация переменных в циклы parfor. Если Embedded Coder обнаруживает циклы, которые не соответствуют parfor спецификации, он не генерирует код и вызывает ошибку.

    Сокращения являются исключением из правила, что итерации цикла должны быть независимыми. reduction variable накапливает значение, которое зависит от всех итераций вместе, но не зависит от порядка итерации. Для получения дополнительной информации см. Раздел «Переменные сокращения».

  • Существует только несколько итераций, которые выполняют некоторые простые вычисления.

    Примечание

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

  • Для Каждой Подсистемы содержит блок S-Function. Сгенерированный код не будет содержать parfor.

Запись кода при помощи циклы parfor

Чтобы запустить for-loops параллельно в сгенерированном коде, запишите код в MATLAB Function или MATLAB System, блок, используя parfor.

  1. Создайте модель Simulink™.

  2. Добавьте MATLAB Function или MATLAB System блок к модели.

  3. Добавьте код к блоку MATLAB Function или MATLAB System.

    function y = access3a(u) %#codegen
    
    %   Copyright 2010 The MathWorks, Inc.
    
    persistent pA;
    if isempty(pA)
        pA = 0;
    end
    A = ones(20,50);
    t = 0;
    
    parfor (i = 1:10,4) 
        A(i,1) = A(i,1) + 1;                    
    end
    
    y = A(1,4) + u + t + pA;

  4. На панели Optimization выберите Maximize execution speed опция из выпадающего списка Приоритет. Параметр Generate parallel for-loops выбирается автоматически. Параметр позволяет компилятору вычислять циклы параллельно.

  5. Соедините блоки.

  6. Создайте модель и сгенерируйте код.

    В сгенерированном коде прагма предписывает компилятору выполнить петлю в параллели OpenMP for-loops посредством многопоточности:

    #pragma omp parallel for num_threads(4 > 
                    omp_get_max_threads() ? omp_get_max_threads() : 4)

    Номер 4 указывает количество потоков обработки.

Поскольку тело цикла может выполняться параллельно в нескольких потоках, оно должно соответствовать определенным ограничениям. Если программное обеспечение Embedded Coder обнаруживает циклы, которые не соответствуют parfor спецификации, это приводит к ошибке. Для получения дополнительной информации см. раздел «Ограничения parfor».

Похожие темы