Нарезанная переменная - это переменная, значение которой может быть разбито на сегменты или срезы, которые затем обрабатываются отдельно различными работниками. Каждая итерация цикла работает с другим срезом массива. Использование нарезанных переменных может уменьшить коммуникацию между клиентом и работниками.
В этом примере работники применяют f
к элементам A
отдельно.
parfor i = 1:length(A) B(i) = f(A(i)); end
Если переменная в parfor
-цикл имеет все следующие характеристики, затем переменная срезается:
Тип индексации первого уровня - первый уровень индексации является либо круглыми скобками, ()
, или скобки, {}
.
Список фиксированных индексов - В круглых скобках первого уровня или скобках список индексов одинаковый для всех вхождений заданной переменной.
Форма индексации - В пределах списка индексов для переменной, ровно один индекс включает переменную цикла.
Форма массива - массив поддерживает постоянную форму. При назначении разрезанной переменной правая сторона назначения не может быть []
или ''
, поскольку эти операторы пытаются удалить элементы.
Тип индексации первого уровня. Для нарезанной переменной первый уровень индексации заключен в обе круглые скобки, ()
, или скобки, {}
.
Вот формы для первого уровня индексации для массивов, которые срезаны и не срезаны.
Не срезано | Нарезанный |
---|---|
A.x | A(...) |
A.(...) | A{...} |
После первого уровня можно использовать любой тип действительного MATLAB® индексация на втором и последующих уровнях.
Переменная A
показанный здесь слева не нарезан; то, что показано справа, срезано.
A.q{i,12} A{i,12}.q
Список фиксированных индексов. В рамках индексации первого уровня разрезанной переменной список индексов одинаковый для всех вхождений заданной переменной.
Переменная A
слева не нарезан, потому что A
индексируется по i
и i+1
в разных местах. В коде справа переменная A
Правильно срезан.
Не нарезанный | Нарезанный |
---|---|
parfor i = 1:k B(:) = h(A(i), A(i+1)); end |
parfor i = 1:k B(:) = f(A(i)); C(:) = g(A{i}); end |
В примере справа показаны вхождения индексации первого уровня с использованием как круглых скобок, так и скобок в одном цикле, что приемлемо.
В следующем примере слева не происходит срез A
потому что индексация A
не во всех местах одно и то же. Пример справа нарезает оба A
и B
. Индексация A
не совпадает с индексацией B
. Однако индексация обоих A
и B
являются индивидуально последовательными.
Не нарезанный | Нарезанный |
---|---|
parfor i=1:10 b = A(1,i) + A(2,i) end |
A = [ 1 2 3 4 5 6 7 8 9 10; 10 20 30 40 50 60 70 80 90 100]; B = zeros(1,10); parfor i=1:10 for n=1:2 B(i) = B(i)+A(n,i) end end |
Форма индексации. В пределах первого уровня индексации для нарезанной переменной только одно выражение индексации имеет вид i
, i+k
, i-k
, или k+i
. Область индекса i
- переменная цикла и k
является скаляр целого числа константой или простой (неиндексированной) широковещательной переменной. Каждое другое выражение индексации является положительной целочисленной константой, простой (неиндексированной) широковещательной переменной, вложенной for
- цикл индексной переменной, двоеточие илиend
.
С i
как переменная цикла, A
переменные, показанные слева, не срезаны, в то время как A
переменные справа срезаны.
Не нарезанный | Нарезанный |
---|---|
A(i+f(k),j,:,3) % f(k) invalid for slicing A(i,20:30,end) % 20:30 not scalar A(i,:,s.field1) % s.field1 not simple broadcast var |
A(i+k,j,:,3) A(i,:,end) A(i,:,k) |
Когда вы используете другие переменные вместе с переменной цикла для индексации массива, вы не можете задать эти переменные внутри цикла. В эффект такие переменные постоянны во время выполнения всей parfor
оператор. Вы не можете объединить переменную цикла с самой собой, чтобы сформировать выражение индекса.
Форма массива. Нарезанная переменная должна поддерживать постоянную форму. Переменная A
показанный здесь, не нарезан:
A(i,:) = [];
A
не срезается, потому что изменение формы нарезанного массива будет нарушать допущения, регулирующие коммуникацию между клиентом и работниками.
Нарезанная переменная может быть переменным входом, переменным выходом или обоими. MATLAB передает срезанные входные переменные от клиента работникам и срезанные выходные переменные от работников обратно клиенту. Если переменная является и входной, и выходной, она передается в обоих направлениях.
В этом parfor
-цикл, A
является нарезанной входной переменной и B
- нарезанная выходная переменная.
A = rand(1,10); parfor ii = 1:10 B(ii) = A(ii); end
Однако, если MATLAB определяет, что в каждой итерации срезанные элементы переменной заданы перед любым использованием, то MATLAB не передает переменную работникам. В этом примере все элементы A
устанавливаются перед любым использованием.
parfor ii = 1:n if someCondition A(ii) = 32; else A(ii) = 17; end % loop code that uses A(ii) end
Переменные sliced-output могут динамически расти через индексированные назначения с значениями по умолчанию, вставленными в промежуточные индексы. В этом примере можно увидеть, что значение по умолчанию 0 было вставлено в нескольких местах в A
.
A = []; parfor idx = 1:10 if rand < 0.5 A(idx) = idx; end end disp(A);
0 2 0 4 5 0 0 8 9 10
Даже если нарезанная переменная не упоминается явно как вход, неявное использование может сделать ее такой. В следующем примере не все элементы A
обязательно устанавливаются внутри parfor
-цикл. Поэтому исходные значения массива получают, удерживают и затем возвращают из цикла.
A = 1:10; parfor ii = 1:10 if rand < 0.5 A(ii) = 0; end end
При некоторых обстоятельствах, parfor
-циклы должны принимать, что работнику могут потребоваться все сегменты разрезанной переменной. В этом примере невозможно определить, какие элементы срезанной переменной будут считываться перед выполнением, поэтому parfor
отправляет все возможные сегменты.
A = 1:10; parfor ii=1:11 if ii <= randi([10 11]) A(ii) = A(ii) + 1; end end
for
- циклы с разрезанными переменнымиКогда вы индексируете нарезанную переменную с вложенной for
-цикл переменная, имейте эти требования в виду:
Нарезанная переменная должна быть заключена в соответствующую for
-цикл.
В этом примере код слева не работает, потому что он индексирует срезанную переменную A
вне вложенного for
-цикл, который определяет j
.
Не срезано | Нарезанный |
---|---|
A = zeros(10); parfor i=1:10 for j=1:10 end A(i,j)=1; end |
A = zeros(10); parfor i=1:10 for j=1:10 A(i,j) = 1; end end |
The области значений of for
- цикл переменная должна быть вектора-строки положительных постоянных чисел или переменных.
В этом примере код слева не работает, потому что он определяет верхний предел вложенного for
-цикл с вызовом функции. Код справа обеспечивает решение путем определения верхнего предела в постоянной переменной за пределами parfor
-цикл.
Не срезано | Нарезанный |
---|---|
A = zeros(10); parfor i=1:10 for j=1:size(A,2) A(i,j)=1; end end |
A = zeros(10); L = size(A,2); parfor=1:10 for j=1:L A(i,j)=1; end end |
for
Цикл не должна назначаться иначе, чем ее for
оператор.
В этом примере код слева не работает, потому что он переназначает for
-цикл переменная внутри for
-цикл. Код справа обеспечивает решение путем присвоения i
во временную переменную t
.
Не срезано | Нарезанный |
---|---|
A = zeros(10); parfor i=1:10 for j=1:10 if i == j j = i; A(i,j) = j; end end end |
A = zeros(10); parfor i=1:10 for j=1:10 if i == j t = i; A(i,j) = t; end end end |