Critical code section inside parfor
    7 views (last 30 days)
  
       Show older comments
    
    Shlomo Geva
 on 17 Feb 2021
  
    
    
    
    
    Commented: Edric Ellis
    
      
 on 22 Feb 2021
            With C++ one can define critical code section inside a parallel for.  
Is there a similar construct that can be used with Matlab?
e.g. suppose that a shared variabe has to be infrequently updated, but must be shared.
With C/C++ we might use a typical construct such as this:
    #pragma omp for
    for (...) {
        // Do something with elements indexed by loop control variable 
        // and use some shared resource in calculations
        if (update_required) {
            #pragma omp critical
            // Critical block can only be entered by 1 thread at a time
            {
                // update shared resource 
            }
        }
    }
For instance, insert a new key-value pair into a shared hashtable inside the loop; a rare event, but nevertheless the update must be safely shared by all executing threads.
0 Comments
Accepted Answer
  Walter Roberson
      
      
 on 17 Feb 2021
        parfor does not share variables with other threads.
Unless you are calling an external function such as https://www.mathworks.com/matlabcentral/fileexchange/28572-sharedmatrix or you are updating a memory mapped file https://www.mathworks.com/help/matlab/ref/memmapfile.html then the only way you can update a variable in another worker is to use a parfor data queue to send the value to the client, and have the client send the value to the other workers.
"global" variables are not shared. graphic objects are not shared. 
2 Comments
  Walter Roberson
      
      
 on 18 Feb 2021
				Oh yes, another possible mechanism: if the workers are all using matFile() on the same file, then in theory the next time they happen to read the variable they would get the new value. However I do not see any documentation that promises that in practice -- the lack of discussion of cache effects suggests that either their is no cache (seems unlikely for performance reasons) or else that the facility was not designed for multiple update (seems more likely.)
More Answers (1)
  Edric Ellis
    
      
 on 18 Feb 2021
        Further to Walter's response, the closest analogy in parfor is a reduction variable. These may appear to be updated by multiple loop iterations concurrently, but the parfor machinery (and language constraints) ensure that the result is computed deterministically with no race conditions. I.e. the following is supported, and completely deterministic.
list = [];
parfor i = 1:100
    list = [list, i];
end
7 Comments
  Walter Roberson
      
      
 on 22 Feb 2021
				A valid spmd pattern is
otherlabs = setdiff(1:numlabs,labIndex);
while true
  while labProbe
    newkv = labRecieve;
    update local hash using newkv{1} key and newkv{2} value
  end
  compute the next thing 
  if the computation required a new hash key 
    labSend({newkey, newvalue}, otherlabs) 
  end
end
This would have to be enhanced to handle shutting down labs gracefully when end of calculating is reached. For example instead of sending a cell a lab could send its own lab index with a tag marking a shut down. The labSend would first labProbe checking for that tag and if it finds it, labRecieve the tag and remove the received lab number from the list otherlabs before going ahead with the labSend to update the others.
  Edric Ellis
    
      
 on 22 Feb 2021
				I would not recommend that pattern, as it can lead to deadlock. labSend does not necessarily complete until the corresponding labReceive has started. Therefore, you can easily end up with all workers stuck trying to call labSend simultaneously (e.g. if they all wish to send on the first iteration). In practice, small messages get sent immediately by labSend using underlying buffering, but it is definitely not a good idea to rely on that. The "safe" version of that pattern unfortunately loses efficiency because it requires a synchronisation point after each "compute the next thing". Something like 
spmd
    while ~done
        compute the next thing
        % all-to-all communication to disseminate values
        if the computation required a new hash key
            toCommunicate = {newkey, newvalue};
        else
            toCommunicate = {};
        end
        allNewKeysAndValues = gcat(toCommunicate);
        updateCache(allNewKeysAndValues);
        done = % some other collective decision
    end
end
See Also
Categories
				Find more on Startup and Shutdown 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!