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!