我有一个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
变量称为h
、a
等,这种情况尤其常见(当然,当变量不是global
时,这也会导致读取不良(
最后,一篇概述使用global
变量的大多数原因的文章通常是个坏主意。
一句话:你想要的是不可能的,通常被认为是不好的做法。