It almost sounds like you're walking a tree (or many trees so... a forest?). Instead of explicitly using
par_iter(), what about using the more general
rayon::scope() to run a closure which will recursively walk the tree, using
Scope::spawn() to do the next level of recursion (possibly) in parallel.
As long as updating an
S can be done independently of neighbouring
S's, you should be able to take mutable references to each field instead of needing any form of synchronisation (
It feels like you're trying to fight your architecture here.... Is it possible to restructure your data in a way that is more amenable to parallelism?
Arc<Mutex<T>> hurts parallelism when you want to frequently access the
T because it's a
Mutex's purpose to make sure only one thread of execution can run at a time.
I'm guessing the
update_a_var_in_s() from your example isn't the real code? Because 2000 items isn't that many, a computer could chew through hundreds of thousands of increment operations in a single second.
If the individual operations are slow, you'll probably get better performance gains by using smarter algorithms (e.g.
O(n log n) instead of
O(n^2)), not collecting into temporary
Vec's, and doing it on a single thread so you can get mutable access without the cost of synchronisation.
In my day job I work with a lot of moderately sized data and a pretty tight latency budget (operations need to complete within a couple hundred milliseconds or the user gets frustrated) and have found that algorithmic improvements can give orders of magnitude better performance than doing the naive thing in parallel... Of course, depending on your task there may not be any smarter algorithms available for you (e.g. updating every item in an array will always require touching every item in the array).