Concurrent writes to array with unspecified (but not UB) outcome?

I have an unusual question. I want to know if there is any mechanism or data structure I could implement that would let multiple threads efficiently/quickly write to the same array concurrently without triggering UB.

I understand that data races are always UB, and I obviously want to avoid that. What I'm trying to figure out is if there's any way to avoid data races that does not impact the performance "too much". Something involving atomics or some kind of efficient queue and dedicated writer thread?

I accept that the written value may be completely unpredictable and unspecified if multiple threads tried to write to the same location.

Context: I'm thinking about this problem because I want to implement some realtime software rendering techniques that don't need to have a 100% "correct" output (demoscene stuff), but it is important that it's fast and doesn't crash/even worse due to UB. Some similar techniques exist where GPU compute shaders write to a shared buffer in an unpredictable way.

My first instinct would be to do atomic operations with Relaxed ordering to not introduce any memory fences. That should guarantee that you always read a value as it was written, but without many guarantees about which value you get if there were multiple concurrent writes.

3 Likes

Do what Java does: make every single write atomic, just using the weakest ordering available to you. Java uses what LLVM calls unordered, which Rust doesn't expose, so Relaxed it is, like 2e71828 said.

1 Like

If you need only concurrent write, I would suggest to manage a separate array for each thread and then merger them somehow at the end.

Atomics are the right way to do this for overlapping ranges. But if you can divide the array with slice::get_disjoint_mut(), then that's probably even better.

1 Like

If the array is small, then multiple threads writing to it will be slow due to the false sharing problem.

If the array is large, use rayon.

3 Likes

Thanks all, I'll try some of this! This is not a very serious project, so experimenting is the primary point of what I'm doing.