Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding race conditions when using parfor in MATLAB

I'm looping in parallel and changing a variable if a condition is met. Super idiomatic code that I'm sure everyone has written a hundred times:

trials = 100;
greatest_so_far = 0;
best_result = 0;

for trial_i = 1:trials
    [amount, result] = do_work();

    if amount > greatest_so_far
        greatest_so_far = amount;
        best_result = result;
    end
end

If I wanted to replace for by parfor, how can I ensure that there aren't race conditions when checking whether we should replace greatest_so_far? Is there a way to lock this variable outside of the check? Perhaps like:

trials = 100;
greatest_so_far = 0;
best_result = 0;

parfor trial_i = 1:trials
    [amount, result] = do_work();

    somehow_lock(greatest_so_far);
    if amount > greatest_so_far
        greatest_so_far = amount;
        best_result = result;
    end
    somehow_unlock(greatest_so_far);
end
like image 624
rhombidodecahedron Avatar asked Sep 15 '25 20:09

rhombidodecahedron


2 Answers

Skewed answer. It does not exactly solve your problem, but it might help you avoiding it.

If you can afford the memory to store the outputs of your do_work() in some vectors, then you could simply run your parfor on this function only, store the result, then do your scoring at the end (outside of the loop):

amount = zeros( trials , 1 ) ;
result = zeros( trials , 1 ) ;

parfor trial_i = 1:trials
    [amount(i), result(i)] = do_work();
end

[ greatest_of_all , greatest_index ] = max(amount) ;
best_result = result(greatest_index) ;

Edit/comment : (wanted to put that in comment of your question but it was too long, sorry).
I am familiar with .net and understand completely your lock/unlock request. I myself tried many attempts to implement a kind of progress indicator for very long parfor loop ... to no avail.

If I understand Matlab classification of variable correctly, the mere fact that you assign greatest_so_far (in greatest_so_far=amount) make Matlab treat it as a temporary variable, which will be cleared and reinitialized at the beginning of every loop iteration (hence unusable for your purpose).

So an easy locked variable may not be a concept we can implement simply at the moment. Some convoluted class event or file writing/checking may do the trick but I am afraid the timing would suffer greatly. If each iteration takes a long time to execute, the overhead might be worth it, but if you use parfoor to accelerate a high number of short execution iterations, then the convoluted solutions would slow you down more than help ...

You can have a look at this stack exchange question, you may find something of interest for your case: Semaphores and locks in MATLAB

like image 53
Hoki Avatar answered Sep 18 '25 16:09

Hoki


The solution from Hoki is the right way to solve the problem as stated. However, as you asked about race conditions and preventing them when loop iterations depend on each other you might want to investigate spmd and the various lab* functions.

like image 28
Thomas Ibbotson Avatar answered Sep 18 '25 17:09

Thomas Ibbotson