Very cool stuff in com.unity.media.utilities

This came to my attention today. I’m seeing an “AtomicFreeList” and an “AtomicQueue” in there. Both of which are multiple-reader and multiple-writer according to the comments in the code

I’d like to know; is there any reason why we’d still want NativeList and NativeQueue instead of these? Are there any caveats? And do they require any specific [DisableSafeties] when using them in jobs?

-edit- read further down

They use Interlocked.CompareExchange, Interlocked.Read etc
One of the objectives of the nativequeue/nativelist implementations was to avoid these.

I’m not too familiar with this. What was the reason for wanting to avoid them?

Performance, I’ll see if i can find an early discussion

-edit-

base choice of words

So, could we say that these new Atomic collections are more geared towards ease-of-use than performance?

As they explicitly label the package as being unsafe I’m not sure they will be promoting use to the public.

“Low-level, unsafe utilities shared by various unity packages”

Seems more like a tool available if have a specific use case and you know what you are doing.

I’m confused. I thought atomic operations are extremely fast and do not lock. That’s the reason for using them…

Sorry I believe you are correct. Bad choice of words. Too early in the morning for me.

Atomics are faster than mutexes (mutexes are built on atomics) but they are not fast. From my limited understanding of x86, usage of atomics flush the store buffer (program order write queue) to the cache lines (roughly the penalty of a branch misprediction) and then the atomic could fail which leads to an actual branch prediction until it succeeds. During this process, none of the other threads can drain their store buffers. On top of this, once the atomic does hit cache, it then invalidates the cache line on all the other threads causing them to have to reload it. So when all the threads are off doing their own thing, an atomic operation is a little stall to the user thread and then all is well again. But when all the threads are trying to do atomics to the same memory, it becomes quite literally a memory traffic jam of epic proportions.

We had a discussion about the different containers and approaches to problems in this thread: ECS Culling

Long story short, NativeList, NativeQueue, NativeStream, and IJobParallelForFilter are all really good options compared to trying to get crazy with atomics. The containers in this new library are for very special cases (and even then I’m still suspicious).

3 Likes

That’s the post I couldn’t find.