Нарезанные переменные

Нарезанная переменная является той, значение которой может быть разбито в сегменты или срезы, на которых затем используют отдельно различные рабочие. Каждая итерация цикла работает над различным срезом массива. Используя нарезанные переменные может уменьшать связь между клиентом и рабочими.

В этом примере рабочие применяют f к элементам A отдельно.

parfor i = 1:length(A)
    B(i) = f(A(i));
end

Характеристики нарезанной переменной

Если переменная в parfor- цикл имеет все следующие характеристики, затем переменная нарезана:

  • Тип Индексации Первого уровня — первый уровень индексации является любой круглыми скобками, (), или фигурные скобки, {}.

  • Фиксированный Список индексов — В круглых скобках первого уровня или фигурных скобках, список индексов является тем же самым для всех случаев данной переменной.

  • Форма Индексации — В рамках списка индексов для переменной, точно один индекс включает переменную цикла.

  • Форма Массива — массив обеспечивает постоянную форму. В присвоении нарезанной переменной правой стороной присвоения не может быть [] или '', потому что эти операторы пытаются удалить элементы.

Тип Индексации Первого уровня. Для нарезанной переменной первый уровень индексации заключен в любой круглые скобки, (), или фигурные скобки, {}.

Вот формы для первого уровня индексации для массивов, которые нарезаны и не нарезаны.

Не нарезанныйНарезанный
A.xA(...)
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

Нарезанные выходные переменные могут вырасти динамически через индексируемые присвоения со значениями по умолчанию, вставленными в промежуточных индексах. В этом примере вы видите, что значение по умолчанию 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
  • Область значений 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

Похожие темы