并行池无法识别全局变量

时间:2018-11-20 20:54:41

标签: matlab parallel-processing global-variables parfor

我有一个要并行运行的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变量在并行循环中可见?

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

2 个答案:

答案 0 :(得分:4)

最简单的建议是:不要使用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

答案 1 :(得分:3)

引用the author of the parallel toolbox

  

GLOBAL数据很难在PARFOR内部使用,因为每个工作程序都是一个单独的MATLAB进程,并且全局变量未从客户端(或任何其他进程)同步到工作程序< / strong>。

强调我的。因此,在工作线程上获取global变量的唯一方法(出于链接文章中提到的原因,这是一个糟糕的主意)是编写一个函数来设置global变量,然后在每个变量上运行工人,然后运行自己的global依赖功能。

引用我的another comment来说明为什么这是一个坏主意:

  

在良好实践方面的一个陷阱是,您可能突然覆盖一个在其他函数中的函数中使用的变量。因此,可能难以跟踪更改,因此,在函数之间来回移动可能会导致意外行为。尤其是在您调用global变量(例如ha等)时发生这种情况(当然,当变量不是global时,也会导致读取错误)

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

底线:您想要的东西是不可能的,通常被认为是不好的做法。