exponenta event banner

Дополнительные примечания по передаче заданий

Количество задач в связном задании

Хотя для взаимодействующего задания создается только одна задача, система копирует эту задачу для каждого работника, выполняющего задание. Например, если связное задание выполняется на четырех работниках, Tasks свойство задания содержит четыре объекта задачи. Первая задача в задании Tasks соответствует задаче, выполняемой работником labindex является 1и так далее, чтобы ID для объекта задачи и labindex для работника, который запустил эту задачу, имеют одинаковое значение. Следовательно, последовательность результатов, возвращаемых fetchOutputs функция соответствует значению labindex и к порядку задач в задании Tasks собственность.

Избежать взаимоблокировки и других ошибок зависимостей

Поскольку код, выполняемый в одном работнике для задания связи, может блокировать выполнение до тех пор, пока соответствующий код не будет выполнен в другом работнике, в заданиях связи существует вероятность взаимоблокировки. Это, скорее всего, произойдет при передаче данных между работниками или при установлении зависимости кода от labindex в if заявление. Некоторые примеры иллюстрируют общие подводные камни.

Предположим, что имеется распределенный массив D, и вы хотите использовать gather для сборки всего массива в рабочей области одного работника.

if labindex == 1
    assembled = gather(D);
end

Причина ошибки в том, что gather функция требует обмена данными между всеми работниками, по которым распределен массив. Когда if оператор ограничивает выполнение одним работником, другие работники, необходимые для выполнения функции, не выполняют оператор. В качестве альтернативы можно использовать gather для сбора данных в рабочую область одного работника: assembled = gather(D, 1).

В другом примере предположим, что требуется перенести данные от каждого работника к следующему работнику справа (определяется как следующий выше labindex). Сначала необходимо определить для каждого работника, какие работники находятся слева и справа.

from_lab_left = mod(labindex - 2, numlabs) + 1;
to_lab_right  = mod(labindex, numlabs) + 1;

Затем попробуйте передать данные по кольцу.

labSend (outdata, to_lab_right);
indata = labReceive(from_lab_left);

Причиной сбоя этого кода является то, что в зависимости от размера передаваемых данных labSend функция может блокировать выполнение в работнике до тех пор, пока соответствующий принимающий работник не выполнит labReceive функция. В этом случае все работники пытаются отправить одновременно, и никто не пытается получить, пока labSend они заблокированы. Другими словами, никто из рабочих не добирается до своих labReceive операторы, потому что все они заблокированы в labSend заявление. Чтобы избежать этой конкретной проблемы, можно использовать labSendReceive функция.