Updating variable inside parfor
Show older comments
Hello,
I have a variable that I want to update inside a parfor loop:
a = 1;
parfor i = 1: 10
a = a + 1;
disp(a);
end
How can I do this? Can I use data queues to do this, if yes, how.
I am new to parallel computing.
My goal is to print the value of a everytime it is updated.
Edit: I was able to do this as below. But it uses a global variable. Is there a better way?
global a
a = 1;
q = parallel.pool.DataQueue;
afterEach(q, @my_increment);
parfor i = 1: 10
send(q, i);
end
function my_increment(m)
global a
a = a + 1;
fprintf('a\n', x);
end
Would using persistent variables be better than this?
Accepted Answer
More Answers (1)
The best way is as you first had it:
a=1;
parfor i = 1: 10
a = a + 1;
end
There is no way, however, that you can get the updates to display to the screen reliably in serial order (including your approach with a global variable). That is because the updates are not being processed serially. They are being processed in parallel.
19 Comments
atharva aalok
on 12 Aug 2023
atharva aalok
on 12 Aug 2023
Edited: atharva aalok
on 12 Aug 2023
Torsten
on 12 Aug 2023
a_new = a_old + 1
atharva aalok
on 12 Aug 2023
Torsten
on 12 Aug 2023
If the result of index i in a for-loop depends on the result of index (i-1) of the for loop, it makes no sense to parallelize. If the operations in a for-loop are independent from each other, you can parallelize.
atharva aalok
on 12 Aug 2023
Edited: atharva aalok
on 12 Aug 2023
Torsten
on 12 Aug 2023
If the for-loop steps in your particular application are independent, why do you waste your time with the attempt to parallelize an application where the for-loop steps depend on each other ?
This works fine but I want to print a, as it gets changed.
You cannot do that because there is no one single version of a that is being changed at a given moment. A different version of a is being incremented on many different processors at once. That's what it means to process in parallel.
If you were using two workers, it would be as if the following two loops are being run on separate computers at the same time,
a1=1;
for i=1:5 %Runs on one worker
a1=a1+1;
end
a2=0;
for j=6:10 %Runs on another worker
a2=a2+1;
end
and then at the very end the results are consolidated,
a=a1+a2;
Given the above, what does it mean to you to "print a as it gets changed"? The variable a doesn't really come into existence until the very end.
atharva aalok
on 12 Aug 2023
Edited: atharva aalok
on 12 Aug 2023
atharva aalok
on 12 Aug 2023
Edited: atharva aalok
on 12 Aug 2023
Torsten
on 12 Aug 2023
a1=1;
for i=1:5 %Runs on one worker
a1=a1+1;
end
a2=0;
for j=6:10 %Runs on another worker
a2=a2+1;
end
Are you sure MATLAB will be able to figure out that it can start with a2 = 0 in this special case ?
Imagine the dependency between left and right hand side were a little more complicated, e.g. a = 2*a instead of a = a+1 ? Would MATLAB be able to differ between these two cases ?
Walter Roberson
on 12 Aug 2023
I wonder if https://www.mathworks.com/matlabcentral/fileexchange/71083-waitbar-for-parfor would be suitable for your purpose ?
@atharva aalok I believe that using the function approach with global variable (or persistent variable) is a possible solution.
No, it is not. Why use parfor at all seeing as you seem to want things to happen serially? Why not just use a regular for loop?
Walter Roberson
on 12 Aug 2023
The thing about reduction variables is that they are effectively write-only except for the implied read to determine the new value. If you were to do
a=a+1;
as a reduction, then the access to a elsewhere in the parfor loop would be effectively blocked -- and if not, then possibly wildly wrong. parfor converts the system into an implied
a_private(INDEX) = 1;
....
end
a = sum(a_private);
atharva aalok
on 13 Aug 2023
Walter Roberson
on 13 Aug 2023
Try the parfor waitbar.
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!