for
Циклы в сгенерированном кодеИтерации параллельного for
циклы могут запуститься одновременно на нескольких ядрах на целевом компьютере. Распараллеливание раздела кода может значительно улучшить скорость выполнения сгенерированного кода. Смотрите, Как циклы parfor Улучшают Скорость Выполнения.
При генерации кода C/C++ из кода MATLAB® можно сгенерировать параллельный for
циклы автоматически. Автоматическое распараллеливание является преобразованием компилятора, которое преобразует последовательный код в многопоточный код без ручного вмешательства.
Автоматическое распараллеливание for
цикл поддерживает эти типы сборки для целей C/C++: MEX, статическая библиотека, динамически подключаемая библиотека и исполняемый файл.
for
Циклы при помощи приложения MATLAB CoderВключить автоматическое распараллеливание for
циклы, в приложении MATLAB Coder™, на шаге Generate Code, выбирают More Settings > Speed > Enable automatic parallelization.
for
Циклы в командной строкеМожно включить распараллеливание for
циклы при помощи интерфейса командной строки. Рассмотрите функцию autoparExample
:
function x = autoparExample(x) %#codegen for i = 10:numel(x) x(i) = sqrt(x(i)); end end
Автоматически сгенерировать параллельный for
циклы, запустите эти команды:
cfg = coder.config('lib'); cfg.EnableAutoParallelization = 1; x = rand(1,2000); codegen -config cfg autoparExample -args {x} -report
Code generation successful: View report
Откройте и смотрите отчет генерации кода.
Наблюдайте Открытую Многопроцессорную обработку (OpenMP) прагмы, сгенерированные выше for
циклы.
void autoparExample(double x[2000])
{
int i;
if (!isInitialized_autoparExample) {
autoparExample_initialize();
}
#pragma omp parallel for num_threads(omp_get_max_threads()) private(i)
for (i = 0; i < 1991; i++) {
x[i + 9] = sqrt(x[i + 9]);
}
}
Поле, подсвеченное в зеленом рядом с циклами, показывает часть кода, который параллелизируется.
Во вкладке Code Insights, под Automatic parallelization issues, вы видите подробную информацию о for
циклы, которые не были параллелизированы в сгенерированном коде.
Например, чтобы просмотреть особое понимание кода, сгенерируйте код снова для autoparExample
функция, которую вы задали в предыдущем разделе. Задайте меньший размер для входных параметров.
cfg = coder.config('lib'); cfg.EnableAutoParallelization = 1; x = rand(1,1000); codegen -config cfg autoparExample -args {x} -report
Сгенерированный код не содержит параллельный for
циклы, потому что размер входных параметров меньше, чем пороговое значение для автоматического распараллеливания. Откройте отчет и нажмите Code Insights > Automatic parallelization issues, чтобы просмотреть подробную информацию о непараллелизированной части кода.
for
ЦиклВы можете хотеть отключить автоматическое распараллеливание конкретного цикла, если тот цикл выполняет лучше в последовательном выполнении. Предотвратить распараллеливание определенного for
цикл, поместите coder.loop.parallelize('never')
прагма сразу перед циклом в вашем коде MATLAB. Эта прагма заменяет EnableAutoParallelization
установка. Кроме того, эта прагма поддерживает только тех for
циклы, которые явным образом заданы в вашем коде MATLAB. Для получения дополнительной информации о явных и неявных циклах смотрите следующий раздел.
Например, генератор кода не параллелизирует этот цикл:
% Pragma to disable automatic parallelization of for-loops coder.loop.parallelize('never'); for i = 1:n y(i) = y(i)*sin(i); end
Смотрите coder.loop.parallelize
.
for
ЦиклыФункция, взятая в качестве примера, autoparExample
используемый в предыдущих разделах содержит явный for
цикл. Но ваш код MATLAB может также содержать неявный for
циклы, которые не появляются явным образом в коде, который вы создаете. Например, функция MATLAB mtimes
умножает две матрицы и поэтому должен выполнить итерации цикла неявно по элементам матрицы.
Автоматическое распараллеливание поддерживает циклы, которые неявны в вашем коде MATLAB. Например, рассмотрите эту функцию autoparExample_implicit
.
function y = autoparExample_implicit(y) %#codegen y = y * 17; % Generates implicit for loop end
Сгенерируйте код путем выполнения этих команд:
cfg = coder.config('lib'); cfg.EnableAutoParallelization = 1; y = rand(1,2000); codegen -config cfg autoparExample_implicit -args {y} -report
Откройте отчет и смотрите сгенерированный код. Сгенерированный код содержит параллельный цикл for для операции умножения.
void autoparExample_implicit(double y[2000])
{
int i;
if (!isInitialized_autoparExample_implicit) {
autoparExample_implicit_initialize();
}
#pragma omp parallel for num_threads(omp_get_max_threads()) private(i)
for (i = 0; i < 2000; i++) {
y[i] *= 17.0;
}
Циклы, содержащие персистентные переменные, не параллелизируются автоматически
Циклы, содержащие внешние вызовы, не параллелизируются автоматически
Функция, не встроенная после автоматического распараллеливания
Циклы, выполняющие операции сокращения, не параллелизируются автоматически
Пустые циклы и while
циклы не параллелизируются автоматически
coder.CodeConfig
| coder.config
| coder.EmbeddedCodeConfig
| coder.loop.parallelize
| coder.MexCodeConfig
| parfor