并行池不识别全局变量

Posted

技术标签:

【中文标题】并行池不识别全局变量【英文标题】:parallel pool not recognizing global variables 【发布时间】:2018-11-20 20:54:40 【问题描述】:

我有一个 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 循环之外声明了全局变量,并希望在循环内访问它们而不需要在并行循环的工作人员之间修改或更新其值.

【问题讨论】:

我认为这个问题与您提供的链接@Adriaan 不同。我已经在 parfor 循环之外声明了全局变量,我想要做的是访问循环内的变量,而不是修改它或跨工人更新它的值 对不起,重读第二个答案,读第一句:“GLOBAL数据在PARFOR内部很难使用,因为每个worker都是一个单独的MATLAB进程,而全局变量不是从客户端(或任何其他进程)同步到工作人员。”强调我的。 Ergo:工具箱的作者告诉你,在parfor 之外(或在循环体中)设置global 是行不通的。所有这一切都可以在parfor 设置globalinside 函数。不理想,但你已经拥有了。 global 反正一般都不好,还不如完全避免。 谢谢@Adriaan。我将尝试重新表述更详细的内容,以便针对我的情况获得更集中的答案。 【参考方案1】:

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

【讨论】:

还有一个问题@Edric,客户端是否可以访问parallel.pool.Constant。我遇到的情况是函数processData() 在模型中被多次调用。其中一些在正常的for 循环内(模型中不可并行的部分)。该函数也在parfor 循环中调用。所以,我希望工人和客户都可以使用这个常量。提前致谢 很遗憾,现在,parallel.pool.Constant 持有的值在客户端不存在。【参考方案2】:

引用the author of the parallel toolbox:

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

强调我的。因此,在工作人员上获取global 变量的唯一方法(由于链接帖子中提到的原因,这是一个坏主意)是编写一个设置global 变量的函数,在每个工作人员上运行它,然后运行你自己的,global-dependent 函数。

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

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

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

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

【讨论】:

以上是关于并行池不识别全局变量的主要内容,如果未能解决你的问题,请参考以下文章

Python多处理:我可以使用更新的全局变量重用进程(已经并行化的函数)吗?

Webpack sass 加载器无法识别全局变量文件

全局变量与局部变量的特点

Eclipse怎么全局搜索替换

如何在 Python 中的多处理期间访问全局变量 [重复]

如何将许多变量和函数从全局环境导出到 foreach 循环?