Parallel pool on function that uses persistent variables
이전 댓글 표시
Obviously parallel computing cannot handle correctly persistent variable, as showed in this minima example.
It seems when runing in parallel, the persistent variable remains unset [] even if I have set it before.
delete(gcp('nocreate')); % delete the current pool if any
ppobj = parpool('local'); %create parallel pool, 'threads' show the same behaviour
BigData = ones(1000);
Store(1,BigData);
FooOutNormalRun = Foo(1) % 1000000, OK
% Run
% FooOutRunWithppj = Foo(1)
% under parallel pool
Future = parfeval(ppobj, @Foo, 1, 1);
[j, FooOutRunWithppj] = fetchNext(Future);
FooOutRunWithppj % returns 0, expected 1000000
FooOutNormalRun = Foo(1) % 1000000, OK
delete(gcp('nocreate'))
%%
function Data = Store(action, Data)
persistent PDATA
if action == 1
PDATA = Data; % Store
elseif action == 2
Data = PDATA; % Retrieve
end
end
%%
function s = Foo(count) %#ok
BigData = Store(2); % Retrieve
s = sum(BigData,'all');
end
Is the limitation mentioned somewhere in the documentation?
And more importantly any workaround (I try to reduce data broadcast in parallel computing, since my BigData is readonly and I don't want it to be copies (broadcasted) to the process, the overhread slows down and requires memory, and in principe I would be able to avoid that.
댓글 수: 1
Bruno Luong
2022년 6월 6일
편집: Bruno Luong
2022년 6월 6일
채택된 답변
추가 답변 (1개)
Edric Ellis
2022년 6월 6일
0 개 추천
As Walter points out, workers (either threads or processes) do not share persistent variable workspaces. I too cannot find this explicitly mentioned in our doc. There's a hint here, but the restriction is more general than just parfor.
Whether you use threads or processes, you still need to arrange for each worker to get access somehow to your BigData. Either the contents need to be copied to the workers, or each worker needs to load/create it for itself. Using parallel.pool.Constant can work with either option. Again, Walter points out that "copying" data to thread-based workers is much more efficient than for process-based workers - although it sounds like current limitations mean that they don't work for you in any case.
댓글 수: 3
Bruno Luong
2022년 6월 6일
Steven Lord
2022년 6월 6일
Edric can correct me if I'm wrong with this example but let's say you had about the most basic persistent variable setup that there is.
function y = myPersistentStorage(x)
% Untested code
persistent y
if nargin == 1
y = x;
end
If you were to call this in a parfor loop with the loop variable value as input and if you could use persistent variables in a parfor, what would the value of y be in myPersistentStorage after the loop exited?
parfor k = 1:100
myPersistentStorage(k); % Update y
end
q = myPersistentStorage; % Retrieve the last value of y
Remember, parfor loop bodies must be order independent. The loop bodies could be executed in any order. So q would not necessarily be 100. It would not necessarily be 1. It could be 2, 99, or "The Answer" of 42.
Edric Ellis
2022년 6월 6일
The constraint on parfor loops being "order independent" is not really possible to enforce, other than at a syntactic level for the loop body itself. Use of persistent is just one way that you could subvert that. I agree that in your example, if somehow the persistent value was brought back to the client after the loop, it could have any value between 1 and 100.
카테고리
도움말 센터 및 File Exchange에서 Parallel for-Loops (parfor)에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!