I've got an array of u8 which I will be partitioning in a complicated way.
Is it possible to update it from multiple rayon tasks? Sort of like this:
let mut pixels = vec![0; w * h];
rayon::scope(|s| {
s.spawn(move |_s| {
my_fn(&mut pixels);
}
}
BTW, I know about into_par_iter, but I can't partition the pixels ahead of time.
I.e. the partitioning scheme will be recursive and will depend on the outcome of some of the tasks.
FYI, I will be passing metadata about the pixels back and forth, which will influence which part of pixels my_fn will be working on, which is not shown here.
I'm getting this error, which prevents me from borrowing pixels afterwards.
| ------ variable moved due to use in closure
...
999 | write_image(&pixels)
| ^^^^^^^ value borrowed here after move
Should I just give up on this design, or is there some way to make it work?
Use an array of atomics. If you never modify the same element from different threads, you can safely use
Ordering::Relaxed(I think this is free? I am not an expert on that topic).If you are unable to change the
Veccreation, you can convert&mut [int]to&mut [Atomic]as they are guaranteed to have the same layout. On nightly, you can usefrom_mut_slice(). On stable, you can create it with little unsafe code:If you want to avoid even that cost (and assuming there is a cost), you can use
UnsafeCellif you never access the same pixel from different threads (but the burden to prove that is on you, as a user of unsafe code). Note thatUnsafeCellis notSyncso you need to wrap it with a custom type implementingSync; on nightly, you can useSyncUnsafeCell.