Matlab appdata是否在并行池中的工作人员之间共享?

Matlab appdata是否在并行池中的工作人员之间共享?,matlab,parallel-processing,global-variables,persistent-storage,app-data,Matlab,Parallel Processing,Global Variables,Persistent Storage,App Data,我正在处理一个调用多个子函数(在同一个文件中)的复杂函数。为了传递数据,偶尔会使用/机制。此外,一些子函数包含持久性变量(初始化一次以便以后保存计算) 我一直在考虑这个函数是否可以在并行池中的多个worker上执行,但我担心可能会出现一些非预期的数据共享(否则每个worker都是唯一的) 我的问题是-我如何判断global和/或persistent和/或appdata中的数据是在工作人员之间共享的还是每个工作人员独有的 一些可能相关的事情: 在我的例子中,任务是完全并行的,它们的结果不应该以任何

我正在处理一个调用多个子函数(在同一个文件中)的复杂函数。为了传递数据,偶尔会使用/机制。此外,一些子函数包含
持久性
变量(初始化一次以便以后保存计算)

我一直在考虑这个函数是否可以在并行池中的多个worker上执行,但我担心可能会出现一些非预期的数据共享(否则每个worker都是唯一的)

我的问题是-我如何判断
global
和/或
persistent
和/或
appdata
中的数据是在工作人员之间共享的还是每个工作人员独有的

一些可能相关的事情:

  • 在我的例子中,任务是完全并行的,它们的结果不应该以任何方式相互影响(并行化只是为了节省时间)
  • 没有创建任何临时文件或文件夹,因此不存在一个工作人员错误读取另一个工作人员留下的文件的风险
  • parfor
    的子函数中创建/分配所有
    持久性
    和appdata存储变量
  • 我知道每个worker都对应一个具有自己内存空间的新进程(大概是,
    global
    /
    persistent
    /
    appdata
    workspace)。基于此,我认为这种分享很可能不会发生。。。但我们如何确定呢

    相关材料:

  • 这很容易测试,我们将分两个阶段进行测试

    步骤1:人工繁殖“工人” 首先,创建以下3个功能:

    %% Worker 1:
    function q52623266_W1
    global a; a = 5;
    setappdata(0, 'a', a);
    someFuncInSameFolder();
    end
    
    接下来,我们启动两个MATLAB实例(代表并行池中的两个不同工作线程),然后在其中一个实例上运行
    q52623266_W1
    ,等待它完成,然后在另一个实例上运行
    q52623266_W2
    。如果数据共享,第二个实例将打印一些内容。这导致(在R2018b上)出现以下情况:

    这意味着数据不共享。到目前为止还不错,但有人可能会想,这是否代表了一个实际的并行池。所以我们可以稍微调整一下我们的函数,然后进入下一步

    步骤2:工人的自动繁殖 运行上述程序,我们得到:

    >> q52623266_Host
    Starting parallel pool (parpool) using the 'local' profile ...
    connected to 2 workers.
    Lab 1: 
      b is now set!
    Lab 2: 
      b is now set!
    

    这同样意味着数据不被共享。请注意,在第二步中,我们使用了
    spmd
    ,在本测试中,它的功能应类似于
    parfor

    还有一个不共享数据的问题

    持久变量甚至不会从当前工作区复制到工作区。

    为了演示,创建了一个带有持久变量的简单函数(MATLAB 2017a):

    然后执行一个简短的脚本:

    testPersist(123); % Set persistent variable to 123.
    tpData = zeros(100,1);
    parfor i = 1 : 100
        tpData(i) = testPersist;
        testPersist(i);
    end
    any(tpData == 0) % This implies the worker started from 0 instead of 123 as specified in the first row.
    
    输出为
    1
    -工作人员忽略父工作区中的123,重新开始

    通过检查
    tpData
    中的值,还可以通过标注“tpData(14)=15-这意味着完成15的工人接着完成14”来显示每个工人是如何完成其工作的

    因此,创建一个worker=创建一个与前面打开的MATLAB实例完全无关的全新MATLAB实例。每个工人都要分开


    我从中得到的教训=不要将简单的持久变量用作模拟配置文件。只要不使用parfor,它就工作得很好,看起来很优雅。。。但后来坏得很厉害。使用对象。

    我的“官方评论”(official comment)(!)没有太多要添加的内容-但无论如何,并行计算工具箱工作进程之间不会共享所有
    全局
    持久
    应用数据
    的内容。(通常人们都希望如此。)@Edric谢谢你的评论。既然你在马身上有一个[员工]标签,那就差不多是正式的了。:)
    >> q52623266_W1
    b is now set!
    
    >> q52623266_W2
    b is now set!
    
    function q52623266_Host
    
    spmd(2)
      if labindex == 1
        setupData();
      end
      labBarrier; % make sure that the setup stage was executed.
      if labindex == 2
        readData();
      end  
    end
    
    end
    
    function setupData
      global a; a = 5;
      setappdata(0, 'a', a);
      someFunc();
    end
    
    function readData
      global a; disp(a);
      disp(getappdata(0,'a'));
      someFunc();
    end
    
    function someFunc()
      persistent b; 
      if isempty(b)
        b = 10;
        disp('b is now set!');
      else
        disp(b);
      end
    end
    
    >> q52623266_Host
    Starting parallel pool (parpool) using the 'local' profile ...
    connected to 2 workers.
    Lab 1: 
      b is now set!
    Lab 2: 
      b is now set!
    
    function [ output_args ] = testPersist( input_args )
    %TESTPERSIST Simple persistent variable test.
    
    persistent var
    
    if (isempty(var))
        var = 0;
    end
    if (nargin == 1)
        var = input_args;
    end
    
    output_args = var;
    
    end
    
    testPersist(123); % Set persistent variable to 123.
    tpData = zeros(100,1);
    parfor i = 1 : 100
        tpData(i) = testPersist;
        testPersist(i);
    end
    any(tpData == 0) % This implies the worker started from 0 instead of 123 as specified in the first row.