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

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

В этом примере работники применяют 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

Переменные 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

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте