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
- цикл не может содержать объявления переменной persistent
или global
.