Несмотря на то, что вы создаете только одну задачу для связывающегося задания, система копирует эту задачу для каждого рабочего, который запускает задание. Например, если связывающееся задание работает на четырех рабочих, Tasks
свойство задания содержит четыре объекта задачи. Первая задача в Tasks
задания свойство соответствует задаче, запущенной рабочим чей
labindex
1
, и так далее, так, чтобы ID
свойство для объекта задачи и labindex
для рабочего, который запустил ту задачу, имеют то же значение. Поэтому последовательность результатов, возвращенных fetchOutputs
функция соответствует значению labindex
и к порядку задач в Tasks
задания свойство.
Поскольку код, запускающийся в одном рабочем для связывающегося задания, может блокировать выполнение, пока некоторый соответствующий код не выполняется на другом рабочем, потенциал для мертвой блокировки существует в связывающихся заданиях. Это, скорее всего, произойдет при передаче данных между рабочими или при создании кодозависимым на labindex
в if
оператор. Некоторые примеры иллюстрируют распространенные ошибки.
Предположим, что у вас есть codistributed массив 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
функция.