并行池无法识别全局变量



我有一个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。我已经在函数processData()中包含了对global变量global Var的调用,但这也不起作用。是否有任何方法可以使global变量在并行循环中可见?

这与这里的问题不同,因为我在parfor循环之外声明了全局变量,并希望在循环中访问它们,而不需要修改或更新并行循环的工作线程之间的值。

最简单的建议是:不要因为这里已经描述/链接的无数原因而使用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

引用并行工具箱的作者:

GLOBAL数据很难在PARFOR中使用,因为每个工作者都是一个单独的MATLAB进程,并且全局变量不会从客户端(或任何其他进程(同步到工作者

强调挖掘。因此,在worker上获得global变量的唯一方法(由于链接文章中提到的原因,这是一个坏主意(是编写一个函数来设置global变量,在每个worker上运行它,然后运行您自己的global相关函数。

引用我的另一条评论来说明为什么这是一个坏主意:

良好实践的陷阱之一是,您可能会突然覆盖其他函数中函数内部使用的变量。因此,很难跟踪更改,因此在函数之间来回切换可能会导致意外行为。如果您将global变量称为ha等,这种情况尤其常见(当然,当变量不是global时,这也会导致读取不良(

最后,一篇概述使用global变量的大多数原因的文章通常是个坏主意。

一句话:你想要的是不可能的,通常被认为是不好的做法。