代码之家  ›  专栏  ›  技术社区  ›  Abdallah Atef

并行池无法识别全局变量

  •  3
  • Abdallah Atef  · 技术社区  · 7 年前

    我有一个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() 但这也不起作用。有什么办法吗 全球的 在并行循环中可见变量?

    这个问题与 here 当我在 parfor 循环并希望在循环内访问它们,而不需要在并行循环的工作进程中修改或更新其值。

    2 回复  |  直到 7 年前
        1
  •  4
  •   Edric    7 年前

    最简单的建议是:不要使用 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 对于上述循环,对每个工作人员只执行一次。但是,如果您有多个邮件,那么不将其发送多次是不够明智的。 帕洛夫 循环。在这种情况下,我建议使用 parallel.pool.Constant . 如何使用它取决于创建的成本 变量 与它的大小相比。如果它很小,但创建成本很高-这意味着您最好只在客户机上创建一次,然后将其发送给员工,如下所示:

    cVar = parallel.pool.Constant(Var);
    

    如果它很大,但构建起来比较快,您可以考虑让每个工人单独构建自己的副本,如下所示:

    cVar = parallel.pool.Constant(@createData); % invokes 'createData' on each worker
    
        2
  •  3
  •   Adriaan Avinash Kumar Jha    7 年前

    引用 the author of the parallel toolbox :

    GLOBAL 数据在内部很难使用 PARFOR 因为每个工人都是一个独立的matlab过程,并且 全局变量不能从客户端(或任何其他进程)同步到工作进程 .

    强调我的。所以唯一的方法就是 global worker上的变量(由于链接的post中提到的原因,这是一个坏主意)是编写一个函数来设置 全球的 变量,在每个工人身上运行它,然后运行自己的, 全球的 -依赖函数。

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

    良好实践中的一个陷阱是,您可以突然覆盖一个变量,该变量在其他函数的函数内部使用。因此,很难跟踪更改,在函数之间来回切换可能会导致意外的行为。如果你打电话给 全球的 变量,比如 h , a ETC(当然,当变量不是 全球的 )

    最后 an article 概述使用 全球的 变量通常是个坏主意。

    底线:你想要的是不可能的,通常被认为是不好的练习。