parfor- Циклыparfor- Переменные Loop являются последовательными увеличивающимися целыми числамиЦиклические переменные в parfor-цикл должен быть последовательным увеличением целых чисел. По этой причине следующие примеры возвращают ошибки:
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Цикл может переполняться, она сообщает об ошибке.
| Условие переполнения | Пример | Решение |
|---|---|---|
Длина | Здесь 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-цикл как переменная, переменная классифицируется в одной из нескольких категорий, показанных в следующей таблице. Убедитесь, что переменные уникально классифицированы и соответствуют требованиям категории. parfor-циклы, которые нарушают требование, возвращают ошибку.
| Классификация | Описание |
|---|---|
| Переменные цикла | Индексы цикла |
| Нарезанные переменные | Массивы, сегменты которых управляются различными итерациями цикла |
| Широковещательные переменные | Переменные, заданные перед циклом, значение которых требуется внутри цикла, но никогда не назначены внутри цикла |
| Переменные сокращения | Переменные, которые накапливают значение через итерации цикла, независимо от порядка итерации |
| Временные переменные | Переменные, созданные внутри цикла и не доступные вне цикла |
Чтобы узнать, какие переменные у вас есть, исследуйте фрагмент кода. Все классификации переменных в таблице представлены в этом коде:

Если вы сталкиваетесь с переменными задачами классификации, рассмотрим эти подходы, прежде чем прибегнуть к более сложному методу преобразования тела parfor-цикл в функцию.
Если вы используете вложенный for-цикл, чтобы индексировать в срезанный массив, вы не можете использовать этот массив в другом месте 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-цикл с использованием назначения записи через точку. В коде слева обе строки в цикле генерируют ошибку классификации. В коде справа в качестве обходного пути можно использовать 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-цикл, во время анализа MATLAB предполагает, что вы ссылаетесь на функцию. Затем во время выполнения, если функцию не удается найти, MATLAB генерирует ошибку. См. «Имена переменных». Для примера в следующем коде f(5) может ссылаться либо на пятый элемент массива с именем f, или функции с именем f с аргументом 5. Если f не определен четко как переменная в коде, MATLAB ищет функцию f на пути, когда код запускается.
parfor i = 1:n ... a = f(5); ... end
parfor- циклыТело a parfor-цикл должен быть прозрачным: все ссылки на переменные должны быть «видны» в тексте кода. Дополнительные сведения о прозрачности см. в разделе Обеспечение прозрачности в циклах parfor или операторах spmd.
Тело parfor-цикл не может содержать global или persistent объявления переменных.