我有一个要并行运行的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
循环之外声明了全局变量,并希望在循环中访问它们,而无需跨工作程序修改或更新其值的并行循环。
答案 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
变量(例如h
,a
等)时发生这种情况(当然,当变量不是global
时,也会导致读取错误)>
最后,an article概述使用global
变量的大多数原因通常是一个坏主意。
底线:您想要的东西是不可能的,通常被认为是不好的做法。