параллельный пул не распознает глобальные переменные - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть программа MATLAB, которую я хочу запустить параллельно, чтобы она работала быстрее.Однако, когда я делаю это, параллельные работники, похоже, не могут получить доступ к глобальным переменным, созданным заранее.Вот как выглядит мой код:

createData  % a .m file that creates a global variable (Var)
parfor i:j
   processData()  % a function that is dependent on some global variables
end

Однако я получаю сообщение об ошибке undefined function or variable Var.Я уже включил вызов global переменных global Var в функцию processData(), но это тоже не работает.Есть ли способ сделать global переменные видимыми в параллельном цикле?

Это не тот же вопрос, что и здесь , поскольку я объявил глобальные переменные вне цикла parfor и хочучтобы получить доступ к ним внутри цикла без необходимости изменять или обновлять его значение среди рабочих параллельного цикла.

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Самый простой совет: не используйте global по множеству причин, уже описанных / связанных здесь.В идеале вы должны реструктурировать свой код следующим образом:

Var = createData(); % returns 'Var' rather than creating a global 'Var'
parfor idx = ...
    % simply use 'Var' inside the parfor loop.
    out(idx) = processData(Var, ...);
end

Обратите внимание, что parfor достаточно умен, чтобы отправлять Var каждому работнику ровно один раз для вышеуказанного цикла.Тем не менее, он недостаточно умен, чтобы не отправлять его несколько раз, если у вас несколько циклов parfor.В этом случае я бы предложил использовать parallel.pool.Constant.Как вы используете, зависит от стоимости создания Var по сравнению с его размером.Если он небольшой, но дорогой в создании - это означает, что вам лучше всего создать его только один раз на клиенте и отправить его рабочим, например:

cVar = parallel.pool.Constant(Var);

Если он большой, но относительнобыстро построить, вы могли бы подумать о том, чтобы каждый из работников создал свою собственную копию независимо, как это:

cVar = parallel.pool.Constant(@createData); % invokes 'createData' on each worker
0 голосов
/ 21 ноября 2018

Ссылаясь на автора параллельного набора инструментов :

GLOBAL данные трудно использовать внутри PARFOR, потому что каждый работник - это отдельный процесс MATLAB, а глобальные переменные не синхронизируются от клиента (или любого другого процесса) к рабочим .

Акцент мой.Таким образом, единственный способ получить переменную global для работника (что является плохой идеей по причинам, указанным в связанном посте), - это написать функцию, которая устанавливает переменные global, запустить ее для каждого работника, а затем запуститьВаша собственная global -зависимая функция.

Ссылаясь на другой мой комментарий , чтобы проиллюстрировать, почему это плохая идея:

Одна из ловушек вВ соответствии с хорошей практикой вы можете внезапно перезаписать переменную, которая используется внутри функции в других функциях.Поэтому может быть трудно отслеживать изменения, и переход туда-сюда между функциями может вызвать неожиданное поведение из-за этого.Это случается особенно часто, если вы называете global переменные такими вещами, как h, a и т. Д. (Это, конечно, делает для плохого чтения также, когда переменная не global)

Инаконец, статья с изложением большинства причин использования global переменных, как правило, плохая идея.

Итог: то, что вы хотите, невозможно, и обычно считается плохой практикой.

...