簡體   English   中英

appdata是否在並行池中的工作者之間共享?

[英]Is appdata shared between workers in a parallel pool?

我正在研究一個復雜的函數,它調用多個子函數(在同一個文件中)。 為了傳遞數據,偶爾會使用setappdata / getappdata機制。 此外,一些子函數包含persistent變量(初始化一次以便稍后保存計算)。

我一直在考慮是否可以在並行池中的幾個worker上執行此函數,但是擔心可能會有一些意外的數據共享(否則每個worker都是唯一的)。

我的問題是 - 如何判斷global和/或persistent和/或appdata是在工作者之間共享還是每個人都是唯一的?

幾個可能相關的事情:

  1. 就我而言, 任務是完全並行的,它們的結果不應以任何方式相互影響(並行化只是為了節省時間)。
  2. 沒有創建任何臨時文件或文件夾,因此不存在一個工作程序錯誤地讀取另一個文件留下的文件的風險。
  3. 所有persistent和appdata存儲的變量都在parfor子函數創建/分配。

我知道每個工作者都對應一個具有自己的內存空間的新進程(可能是global / persistent / appdata工作空間)。 基於此以及在此官方評論中 ,我會說這種共享很可能不會發生......但我們如何確定呢?

相關材料:

  1. 這個Q&A
  2. 此文檔頁面

這非常簡單,我們將分兩個階段進行測試。

第1步:“工人”的手工產卵

首先,創建這3個功能:

%% Worker 1:
function q52623266_W1
global a; a = 5;
setappdata(0, 'a', a);
someFuncInSameFolder();
end

%% Worker 2:
function q52623266_W2
global a; disp(a);
disp(getappdata(0,'a'));
someFuncInSameFolder();
end

function someFuncInSameFolder()
  persistent b; 
  if isempty(b)
    b = 10;
    disp('b is now set!');
  else
    disp(b);
  end
end

接下來,我們啟動2個MATLAB實例(代表並行池的兩個不同工作者),然后在其中一個上運行q52623266_W1 ,等待它完成,然后在q52623266_W2上運行q52623266_W2 如果數據共享的,第2 實例將打印的東西。 結果(在R2018b上):

>> q52623266_W1
b is now set!

>> q52623266_W2
b is now set!

這意味着不共享數據。 到目前為止一直很好,但有人可能想知道這是否代表了一個真正的並行池。 所以我們可以調整一下我們的功能,然后繼續下一步。

第2步:自動產生工人

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!

這也意味着數據不會被共享 需要注意的是,在第二個步驟中,我們使用spmd ,這應該功能類似於parfor本次測試的目的。

還有另一種不共享的數據讓我感到困惑。

永久變量甚至不會從當前工作空間復制到工作者。

為了演示,創建了一個帶有持久變量的簡單函數(MATLAB 2017a):

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.

輸出為1 - 工作人員忽略了父工作空間中的123並重新開始。

檢查tpData的值還會顯示每個工作人員如何通過記錄“tpData(14)= 15來完成其工作 - 這意味着完成15個工作的工人繼續執行14個下一個工作”

因此,創建一個worker =創建一個全新的MATLAB實例,與您在前面打開的MATLAB實例完全無關。 對於每個工人分開。

從中獲得的教訓=不要使用簡單的持久變量作為模擬配置文件。 只要沒有使用parfor,它工作得很好,看起來很優雅......但之后又破壞了。 使用對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM