并行池不识别全局变量

parallel pool not recognizing global variables

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

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

引用 the author of the parallel toolbox:

GLOBAL data is hard to use inside PARFOR because each worker is a separate MATLAB process, and global variables are not synchronised from the client (or any other process) to the workers.

强调我的。因此,在 worker 上获得 global 变量的唯一方法(由于链接 post 中提到的原因,这是一个坏主意)是编写一个设置 global 变量的函数, 运行 在每个 worker 上,然后 运行 你自己的 global 依赖函数。

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

One of the pitfalls in terms of good practise is that you can suddenly overwrite a variable which is used inside a function in other functions. Therefore it can be difficult to keep track of changes and going back and forth between functions might cause unexpected behaviour because of that. This happens especially often if you call your global variables things like h, a etc (this of course makes for bad reading also when the variable is not global)

最后 an article 概述使用 global 变量的大部分原因通常不是一个好主意。

底线:你想要的是不可能的,而且通常被认为是不好的做法。

最简单的建议是:由于已经 described/linked 的无数原因,不要使用 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