Multithreading
Multithreading, the simultaneous iteration and modification of entities for extra speed.
Imagine that you have millions of entities and you want to move them all. It gets a bit difficult on a CPU core. But we have a solution for that too!
This is not a problem, because Arch comes with its own JobScheduler
. This does not generate any garbage and is incredibly fast, even has dependencies and co. What more could you want? Let's be honest!
Setup
Not much is needed to set up multithreading. You set it up, you know it and that's it!
// Create Scheduler and assign it to world
var jobScheduler = new(
new JobScheduler.Config
{
ThreadPrefixName = "Arch.Samples",
,
MaxExpectedConcurrentJobs = 64,
StrictAllocationMode = false,
}
);
// To dispose the JobScheduler at the end of the lifecycle.
jobScheduler.Dispose();
Example
Wonderful, now we have set up the JobScheduler
, all we need to do is let it work to utilise the full capacity of our power!
var queryDesc = new QueryDescription().WithAll<Dwarf, Position, Velocity>();
(in queryDesc, {
Move(ref pos, ref vel);
});
And now we have EVEN more power to march our armies, marvellous, isn't it? Your computer will probably take off, but it's worth it.
Of course, every form of Query
is supported again. Even inline queries.
public struct VelocityUpdate : IForEach<Position, Velocity> {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Update(ref Position pos, ref Velocity vel) {
Move(ref pos, ref vel);
}
}
world.InlineParallelQuery<VelocityUpdate, Position, Velocity>();
Each of these calls, whether world.ParallelQuery
or world.InlineParallelQuery
, will block the main thread until the Query
has been processed. The processing itself still takes place in parallel, but the main thread waits before continuing.
Lowlevel
If this is all too high level for you, there is also the option of tackling the problem further down. Not below the belt, of course!
public struct VelocityUpdate : IChunkJob{
public void Execute(ref Chunk chunk) {
ref var positions = ref chunk.GetFirst<Position>();
ref var velocities = ref velocity.GetFirst<Velocity>();
foreach(var entity in chunk){
ref var position = ref Unsafe.Add(ref positions, entity);
ref var velocity = ref Unsafe.Add(ref velocities, entity);
Move(ref position, velocity);
}
}
}
world.InlineParallelChunkQuery(in query, );
And you'll have even more power for everything you set out to do... honestly, what do you want with so much power anyway?
Last updated
Was this helpful?