parfor- Петлиparfor-Контурные переменные являются последовательными увеличивающимися целыми числамиПеременные цикла в parfor-loop должен быть последовательными возрастающими целыми числами. По этой причине следующие примеры возвращают ошибки:
parfor i = 0:0.2:1 % not integers parfor j = 1:2:11 % not consecutive parfor k = 12:-1:1 % not increasing
iValues = 0:0.2:1; parfor idx = 1:numel(iValues) i = iValues(idx); ... end
parfor- ПетлиЕсли MATLAB ® обнаруживает, что parforПеременная -loop может переполняться, она сообщает об ошибке.
| Условие переполнения | Пример | Решение |
|---|---|---|
Длина | Здесь MATLAB сообщает об ошибке, так как parfor idx=int8(-128:127) idx; end | Использовать больший тип данных для parfor idx=-128:127 int8(idx); end |
Начальное значение | Здесь MATLAB сообщает об ошибке, так как parfor idx=uint32(0:1) idx; end |
|
parfor- ПетлиКогда MATLAB распознает имя в parfor-loop как переменная, переменная классифицируется в одной из нескольких категорий, как показано в следующей таблице. Убедитесь, что переменные однозначно классифицированы и соответствуют требованиям к категории. parfor- циклы, нарушающие требование, возвращают ошибку.
| Классификация | Описание |
|---|---|
| Переменные цикла | Индексы цикла |
| Разрезанные переменные | Массивы, сегменты которых обрабатываются различными итерациями цикла |
| Переменные широковещательной передачи | Переменные, определенные до цикла, значение которых требуется внутри цикла, но никогда не назначается внутри цикла |
| Переменные сокращения | Переменные, накапливающие значение в итерациях цикла независимо от порядка итераций |
| Временные переменные | Переменные, созданные внутри цикла и не доступные за его пределами |
Чтобы узнать, какие переменные у вас есть, изучите фрагмент кода. Все классификации переменных в таблице представлены в этом коде:

Если вы сталкиваетесь с проблемами классификации переменных, рассмотрите эти подходы, прежде чем прибегнуть к более сложному методу преобразования тела parfor-закольцовывание в функцию.
При использовании вложенного for-loop для индексирования в разрезованный массив, этот массив нельзя использовать в другом месте в parfor-луп. Код слева не работает, так как A разрезается и индексируется внутри вложенного for-луп. Код справа работает, потому что v присвоен A вне вложенного цикла. Можно вычислить всю строку, а затем выполнить одно назначение для разделенных выходных данных.
| Инвалид | Действительный |
|---|---|
A = zeros(4, 10); parfor i = 1:4 for j = 1:10 A(i, j) = i + j; end disp(A(i, 1)) end |
A = zeros(4, 10); parfor i = 1:4 v = zeros(1, 10); for j = 1:10 v(j) = i + j; end disp(v(1)) A(i, :) = v; end |
Код слева не работает, так как переменная x в parfor не может быть классифицирован. Невозможно классифицировать эту переменную, так как существует несколько назначений различным частям x. Поэтому parfor не может определить, существует ли зависимость между итерациями цикла. Код справа работает, потому что вы полностью перезаписываете значение x. parfor теперь можно однозначно определить, что x является временной переменной.
| Инвалид | Действительный |
|---|---|
parfor idx = 1:10 x(1) = 7; x(2) = 8; out(idx) = sum(x); end |
parfor idx = 1:10 x = [7, 8]; out(idx) = sum(x); end |
В этом примере показано, как разрезать поле структурированного массива. Посмотрите struct для получения подробной информации. Код слева не работает, так как переменная a в parfor не может быть классифицирован. Невозможно классифицировать эту переменную, так как форма индексирования недопустима для разделенной переменной. Первый уровень индексации не является операцией индексирования с разделением, даже если поле x из a кажется, он правильно разрезан. Код справа работает, потому что вы извлекаете поле struct в отдельную переменную tmpx. parfor теперь можно правильно определить, что эта переменная разделена. Как правило, нельзя использовать поля structs или свойства объектов в виде разделенных входных или выходных переменных в parfor.
| Инвалид | Действительный |
|---|---|
a.x = []; parfor idx = 1:10 a.x(idx) = 7; end |
tmpx = []; parfor idx = 1:10 tmpx(idx) = 7; end a.x = tmpx; |
Невозможно создать структуру в parfor-loop с использованием назначения точечных обозначений. В коде слева обе строки внутри цикла генерируют ошибку классификации. В коде справа в качестве обхода можно использовать struct для создания структуры в цикле или в первом поле.
| Инвалид | Действительный |
|---|---|
parfor i = 1:4 temp.myfield1 = rand(); temp.myfield2 = i; end |
parfor i = 1:4 temp = struct(); temp.myfield1 = rand(); temp.myfield2 = i; end parfor i = 1:4 temp = struct('myfield1',rand(),'myfield2',i); end |
Нельзя использовать поля структуры как секционированные входные или выходные массивы в parfor-луп. Другими словами, переменную цикла нельзя использовать для индексации элементов поля структуры. В коде слева обе строки цикла генерируют ошибку классификации из-за индексирования. В коде справа в качестве обходного решения для разделенных выходных данных используются отдельные разделенные массивы в цикле. Затем присваиваются поля структуры после завершения цикла.
| Инвалид | Действительный |
|---|---|
parfor i = 1:4 outputData.outArray1(i) = 1/i; outputData.outArray2(i) = i^2; end |
parfor i = 1:4 outArray1(i) = 1/i; outArray2(i) = i^2; end outputData = struct('outArray1',outArray1,'outArray2',outArray2); |
Обходным решением для разрезанного ввода является назначение поля структуры отдельному массиву перед циклом. Этот новый массив можно использовать для разрезанных входных данных.
inArray1 = inputData.inArray1; inArray2 = inputData.inArray2; parfor i = 1:4 temp1 = inArray1(i); temp2 = inArray2(i); end
parfor- закольцовывать в функциюЕсли все остальные ошибки, обычно можно решить проблемы классификации переменных в parfor- петли путем преобразования тела parfor-закольцовывание в функцию. В коде слева анализатор кода помечает проблему с переменной y, но не может ее разрешить. В коде справа вы решаете эту проблему, преобразуя тело parfor-закольцовывание в функцию.
| Инвалид | Действительный |
|---|---|
function parfor_loop_body_bad data = rand(5,5); means = zeros(1,5); parfor i = 1:5 % Code Analyzer flags problem % with variable y below y.mean = mean(data(:,i)); means(i) = y.mean; end disp(means); end |
function parfor_loop_body_good data = rand(5,5); means = zeros(1,5); parfor i = 1:5 % Call a function instead means(i) = computeMeans(data(:,i)); end disp(means); end % This function now contains the body % of the parfor-loop function means = computeMeans(data) y.mean = mean(data); means = y.mean; end Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers.
0.6786 0.5691 0.6742 0.6462 0.6307 |
Если используется имя, которое MATLAB не может однозначно различить как переменную внутри parfor-loop, во время синтаксического анализа MATLAB предполагает, что вы ссылаетесь на функцию. Затем во время выполнения, если функция не может быть найдена, MATLAB генерирует ошибку. См. раздел Имена переменных. Например, в следующем коде f(5) может ссылаться либо на пятый элемент массива с именем fили к функции с именем f с аргументом 5. Если f не определен четко как переменная в коде, MATLAB ищет функцию f на пути при запуске кода.
parfor i = 1:n ... a = f(5); ... end
parfor- петлиТело parfor-loop должен быть прозрачным: все ссылки на переменные должны быть «видимыми» в тексте кода. Дополнительные сведения о прозрачности см. в разделе Обеспечение прозрачности в пакетах-петлях или инструкциях spmd.
Тело parfor-loop не может содержать global или persistent объявления переменных.