parfor
- Циклыparfor
- Переменные цикла являются последовательными увеличивающимися Целыми числамиПеременные цикла в 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
может теперь решить правильно, что эта переменная нарезана. В общем случае вы не можете использовать поля struct
s или свойства объектов как нарезанные переменные ввода или вывода в 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); | 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); % This function now contains the body % of the parfor-loop function means = computeMeans(data) y.mean = mean(data); means = y.mean; 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 генерирует ошибку. Смотрите Имена переменных (MATLAB). Например, в следующем коде f(5)
мог отослать любого к Пятому элементу массива под названием f
, или к функции с именем f
с аргументом 5
. Если f
ясно не задан как переменная в коде, MATLAB ищет функциональный f
на пути, когда код запускается.
parfor i = 1:n ... a = f(5); ... end
parfor
- циклыТело parfor
- цикл должен быть прозрачным: все ссылки на переменные должны отобразиться в тексте кода. Для получения дополнительной информации о прозрачности, смотрите, Гарантируют Прозрачность в циклах parfor или spmd Операторах.
Тело parfor
- цикл не может содержать global
или persistent
объявления переменной.