Нарезанная переменная является той, значение которой может быть разбито в сегменты или срезы, на которых затем используют отдельно различные рабочие. Каждая итерация цикла работает над различным срезом массива. Используя нарезанные переменные может уменьшать связь между клиентом и рабочими. Только те срезы, необходимые рабочему, отправляются в него, когда это начинает работать над конкретной областью значений индексов.
В этом примере срез 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(end + 1) = i;
В первом случае A
не нарезан, потому что изменение формы нарезанного массива нарушило бы предположения, управляющие связью между клиентом и рабочими.
Во втором A
не является нарезанный вывод, потому что он не индексируется на переменной цикла.
Все нарезанные переменные имеют характеристики того, чтобы быть вводом или выводом. Нарезанная переменная может иногда иметь обе характеристики. MATLAB передает нарезанные входные переменные от клиента рабочим и нарезанные выходные переменные от рабочих назад клиенту. Если переменная является оба вводом и выводом, она передается в обоих направлениях.
В этом parfor
- цикл, r
является нарезанной входной переменной, и b
является нарезанной выходной переменной.
a = 0; z = 0; r = rand(1,10); parfor ii = 1:10 a = ii; z = z + ii; b(ii) = r(ii); end
Однако, если в каждой итерации, каждая ссылка на элемент массива установлена, прежде чем это будет использоваться, переменная не является нарезанной входной переменной. В этом примере установлены все элементы A
, и затем только те фиксированные значения используются.
parfor ii = 1:n if someCondition A(ii) = 32; else A(ii) = 17; end loop code that uses A(ii) end
Нарезанные выходные переменные могут вырасти динамически через индексируемые присвоения со значениями по умолчанию, вставленными в промежуточных индексных положениях. В этом нарезанном переменном примере вы видите, что значение по умолчанию 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
обоими нарезанной переменной ввода и вывода.
A = 1:10; parfor ii = 1:10 if rand < 0.5 A(ii) = 0; end end
Вы не можете использовать скалярное расширение, чтобы задать множество значений, присвоенное нарезанному выходному массиву. Например, следующий код пытается расширить значение idx
для присвоения на каждый элемент вектора, заданного x(:,idx)
; это действие генерирует ошибку.
x = zeros(10,12); parfor idx = 1:12 x(:,idx) = idx; end
Следующий код предлагает предложенное обходное решение для этого ограничения.
x = zeros(10,12); parfor idx = 1:12 x(:,idx) = repmat(idx,10,1); end