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

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

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