2
\$\begingroup\$

Say we have a parallel job (implementing IJobParallelFor) which requires a large array (>100,000 items) as an input to do some complicated processing. After said job is finished, I'd like to return a portion of those items that have passed certain checks.

Specifically, I'd like to check if >100,000 Vector3's satisfy a certain criteria. If they do, I'd like to add them to a list so that I can continue operating on that data in the main thread (or in other jobs).

The issue is that we can't use a NativeList to call .Add() because that data structure doesn't support parallel writing. It is also not viable to use a NativeArray because it requires its size to be initialized ahead of time, and we don't know how many items we are going to return.

What is a good way to solve this problem?

\$\endgroup\$
1
  • \$\begingroup\$ It sounds like IJobParallelFilter might be helpful here, but I'm finding the documentation very lacking. 😥 \$\endgroup\$
    – DMGregory
    Commented Jan 5, 2022 at 15:52

2 Answers 2

2
\$\begingroup\$

Use NativeQueue for your results, then obtain a NativeQueue<T>.ParallelWriter for it using results.AsParallelWriter(). It exposes a method Enqueue(T) to add elements to the queue.

You can then later read from that queue by copying it to an array using results.ToArray() or by processing the queue using a while(results.TryDequeue(out result)) { loop.

The NativeList also offers a parallel writer, by the way, but that one does not offer operations which exceed the initial capacity.

\$\endgroup\$
1
  • \$\begingroup\$ I also just found the NativeStream which might also be an option, but seems more suitable for a scenario where the result-set is larger than the number of iterations of the IJobParallelFor, not smaller. \$\endgroup\$
    – Philipp
    Commented Jan 5, 2022 at 16:06
1
\$\begingroup\$

You could use a NativeArray<bool> IsValid to indicate which items require some more processing.

Items can then be aggregated in one place (e.g. in another IJob in a loop); or the flag can be used in the followup method in the next job to quit early.

This has the advantage of fixed-size, low synchronization overhead. It requires a tiny bit more RAM. Cache locality is sometimes better, sometimes worse.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .