Glowstone icon indicating copy to clipboard operation
Glowstone copied to clipboard

Parallelism Pulse entities in parallel using divide and conquer

Open Hagvan opened this issue 6 years ago • 5 comments

Utilizes CPU resources better. I tested this using artificial load inside GlowEntity.pulse() method - each pulse every entity generates 10000 random integers. Here are my benchmarks (CPU: Ryzen 2600X): A message is shown every 120 ticks inside each world thread.

Single threaded single thread

ForkJoinPool forkjoinpool

Possible concerns: I know in the future AI for mobs will be added and right now I don't know for sure if it will affect it. What I did is just speed up iteration inside the GlowWorld.pulse() method.

Hagvan avatar Jan 23 '19 20:01 Hagvan

Would it be possible to use the forkJoinPool branch and make these as GlowTasks?

mastercoms avatar Jan 26 '19 16:01 mastercoms

Just re-iterating (excuse the pun) what I said in discord,

Would the Spliterator.trySplit not be a bit more concise? i.e. (taken from https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html)

static <T> void parEach(TaggedArray<T> a, Consumer<T> action) {
   Spliterator<T> s = a.spliterator();
   long targetBatchSize = s.estimateSize() / (ForkJoinPool.getCommonPoolParallelism() * 8);
   new ParEach(null, s, action, targetBatchSize).invoke();
 }

 static class ParEach<T> extends CountedCompleter<Void> {
   final Spliterator<T> spliterator;
   final Consumer<T> action;
   final long targetBatchSize;

   ParEach(ParEach<T> parent, Spliterator<T> spliterator,
           Consumer<T> action, long targetBatchSize) {
     super(parent);
     this.spliterator = spliterator; this.action = action;
     this.targetBatchSize = targetBatchSize;
   }

   public void compute() {
     Spliterator<T> sub;
     while (spliterator.estimateSize() > targetBatchSize &&
            (sub = spliterator.trySplit()) != null) {
       addToPendingCount(1);
       new ParEach<>(this, sub, action, targetBatchSize).fork();
     }
     spliterator.forEachRemaining(action);
     propagateCompletion();
   }
 }

BEllis avatar Jan 28 '19 23:01 BEllis

Thinking about it more, I would really like to have real world situations be tested on this, because of cache locality, world access, and more that would be important to actual entity simulation and AI.

Would you be able to make a more valid test scenario for this PR rather than just generating random numbers?

mastercoms avatar Jan 31 '19 22:01 mastercoms

Sorry I was away for a while. I'll try to use actual AI if it is ready at this point.

Hagvan avatar Apr 07 '19 17:04 Hagvan

It isn't ready, but we can hold this PR until then.

mastercoms avatar Apr 07 '19 17:04 mastercoms