Persistent Variables Not Persistent After Parfor Loops

4 次查看(过去 30 天)
I have noticed that if you have a parfor loop (1 worker) within which several functions with persistent variabls are called, the functions do not retain the persistent variables if you would recall them after the parfor loop in a regular for loop.
For instance I have the following parfor loop:
=============================MAIN BODY
clear functions
a=[0,0];
parfor (i=1:2,1)
if mod(i,2)==1
a(i) = func1(i);
else
a(i) = func2(i);
end
end
disp(a)
for i=1:2
if mod(i,2)==1
a(i) = func1(i);
else
a(i) = func2(i);
end
end
disp(a)
disp('====')
============================= FUNC1
function result = func1(i)
persistent kapa
if isempty(kapa) kapa = 1; end
result=kapa*i;
kapa = kapa*2;
============================= FUNC2
function result = func2(i)
persistent kapa
if isempty(kapa) kapa = 3; end
result=kapa*i;
kapa = kapa*2;
=============================
Notice I'm using only 1 worker so there would be no conflict with persistent variables being mixed up in the parfor loop.
In other words, my question is: shouldn't persistent variables be retained inside the function no matter who calls them or how they're called (as long as there are no conflicts)? Are persistent variables stored in the workers only and the client has no knowledge about them? And if this is the case, is there a way to make the persistent variables in the workers be known to the client?
I would appreciate any comments.

回答(3 个)

Jan
Jan 2011-9-25
Of course persistent variables must be treated independently if used inside a PARFOR loop. Be aware that the different threads of a PARFOR loop run in parallel. Which of the set of threads should be responsible for the final value of the PERSISTENT variable?
It is an intented effect in parallel processing, that persistent variables are local to the thread.

Daniel Shub
Daniel Shub 2011-9-25
I am not sure how MATLAB cleans up memory in parfor loops (and hence if you can keep persistent variables).
Why not just have func* take and return two arguments ...
function [result, kappa] = func1(i, kappa)
if isempty(kapa) kapa = 1; end
result=kapa*i;
kapa = kapa*2;
end
function [result, kappa] = func2(i, kappa)
if isempty(kapa) kapa = 3; end
result=kapa*i;
kapa = kapa*2;
end
clear functions
a=[0,0];
kappa1 = [];
kappa2 = [];
parfor (i=1:2,1)
if mod(i,2)==1
[a(i), kappa1] = func1(i, kappa1);
else
[a(i), kappa2] = func2(i, kappa2);
end
end
  2 个评论
Yashar Mehmani
Yashar Mehmani 2011-9-26
编辑:Yashar Mehmani 2017-10-27
Hi Daniel, Thanks a lot for the response. Unfortunately I really do need to use persistent variables. See the mini program I've posted above is just an over-simplified version of the actual program I have.
Just as a short explanation of what my actual code does: The main body of the program (containing the parfor loop), refers to several "packages" (folders named with a + sign) and runs a series of subroutines in them which need to remember what the final values of those persistent variables are before it exits the package. This is because there is an even bigger "time loop" that contains the parfor loop, and everytime the program progresses through time, persistent variables in these packages are updated based on their previous values.
I hope it makes sense. Do you know of a way to keep them?
Daniel Shub
Daniel Shub 2011-9-26
If you don't want to return the values, you can save the values as a mat file. This is a little harder to manage since clearing the function will not clear the persistent variable.

请先登录,再进行评论。


Konrad Malkowski
Konrad Malkowski 2011-11-8
This is expected behavior.
The reason for this is as follows. When you type matlabpool open local 4, you start 4 additional MATLAB workers (You can verify this by checking Task Manager). These are headless workers.
These workers perform computations only when executing code inside of PARFOR or SPMD blocks. These workers use sockets to communicate with the client MATLAB (i.e., the MATLAB on your desktop).
As each of these workers is an independent program (process) with its own memory, each worker has its own local copy of the functions called within PARFOR/SPMD and as a result its own local copy of persistent variables associated with the functions. The workers also do not know the contents of memory of client, and vice-versa. If you need to share information between workers, or client and workers you will need to explicitly instrument such communication.
It appears to me that you have reached a point at which you will have to redesign your program for parallel computing. In general when doing parallel computing you should avoid relying on on persistent variables and global variables (as these will now be local to a worker, not the whole program).
One of the workarounds could be to use SPMD and keep a copy of persistent variables per worker. You will be responsible for manually partitioning the work between workers and communicating updates to persistent variables using labSend, labReceive, labBroadcast as necessary.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by