Heya,
I’m working on my own concurrent list collection and I wanted to start off more simple and increase the complexity (and hopefully performance) from there. I noticed after I ironed out all the crashes that on a parallel job, when I add to the collection from multiple threads, it performance at par or lower performance than adding to the collection from a single thread. I have a few ideas as to how to combat this, however I want to know what the actual issue is.
The reason I don’t use NativeList.ParallelWriter is because of the syncing when adding an element. My container works by allocating multiple buffers and another buffer for keeping track of the lengths of each buffer. For simplicity’s sake, the actual data buffers are part of one larger buffer (just a void*) that holds all the data and can be indexed simply with the buffer index (usually the threadID) and the size of each buffer (each buffer is a fixed size). However, I’m suspicious that reading and writing from this large buffer with UnsafeUtility.readarrayelement/writearrayelement is causing thread syncs of some kind, for using two threads to add to the collection takes the same time as one. Of course this wouldn’t be as bad in real use cases where there is more calculation than the actual writing to the buffer, but this is still a concern.
I’m thinking that my main buffer should point to an array of structs that have the length and buffer pointer in one spot as to avoid two writes (one to data buffer and one to lengths buffer), but doing so would require the same amount of accesses, plus I’m not sure it would be faster due to requiring multiple allocations for each buffer instead of one singular large allocation (I guess on the other hand it would make resizing far easier when I want to move away from the fixed collection paradigm). Would doing something like this be faster?
All in all, why is multiple threads accessing the same void* degrading performance? Is there some syncing going on with UnsafeUtility? Is there something inherently with accessing the same pointer from multiple threads, if so, how to combat this without creating a struct with 16 seperate void*? Any ideas?
Thanks. Can post code and benchmarks if necessary.