Vixen
02b45cc4
csharp
public sealed class JobScheduler

Persistent worker threads, a dependency graph, and work stealing. Frame work runs here.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

Why not the thread pool. The .NET thread pool is tuned for throughput over an unbounded stream of independent work, and its hill-climbing heuristic responds to a busy period by injecting threads — on a schedule measured in hundreds of milliseconds, against a frame budget measured in single digits. A frame's work is also not independent: it is a graph with a deadline, and the pool has no way to express that. So: a fixed set of threads that exist for the lifetime of the process, and a graph the scheduler resolves itself.

Shape. WorkerCount workers, one fewer than the processor count, because the thread that drives the frame is the missing one and it participates — a call to Complete executes ready work while it waits instead of idling. Each worker owns a WorkStealingDeque; threads that are not workers push to a shared queue. A worker out of its own work takes from the shared queue, then steals. WorkerCount may be zero, which leaves only the participating thread — see IsSingleThreaded.

Cost of scheduling. Nothing on the path from Schedule``1 to the job running allocates. The job struct is copied into a preallocated array; the slot comes from a preallocated ring; the work item is a Int64 in a preallocated buffer. A job type is generic all the way down, so there is no boxing and no delegate.

Thread-safe: any thread may schedule, and any thread may complete.

Fields and properties (8)

  • public const bool SafetyChecksEnabled

    Whether the debug-only scheduler assertions are compiled into this build.

  • public const int MaxJobsInFlight

    How many jobs one scheduler can have in flight.

  • public const int MaxSchedulers

    How many schedulers can exist at once.

  • public int WorkerCount

    How many worker threads this scheduler owns, not counting threads that help.

  • public bool IsSingleThreaded

    Whether this scheduler owns no threads and runs everything on its callers.

  • public int Id

    This scheduler's index in the process-wide table. Carried by every handle it issues.

  • public bool IsWorkerThread

    Whether the calling thread is one of this scheduler's workers.

  • public int OutstandingJobs

    How many jobs are scheduled and not yet complete.

Methods (10)

  • public JobScheduler()

    Creates a scheduler with one worker per processor beyond the calling thread.

  • public JobScheduler(int workerCount)

    Creates a scheduler with a chosen number of workers.

  • public JobHandle Schedule<TJob>(in TJob job, JobHandle dependsOn = default(JobHandle)) where TJob : struct, IJob

    Schedules a job to run once, after has finished.

  • public JobHandle Schedule<TJob>(in TJob job, ReadOnlySpan<JobHandle> dependsOn) where TJob : struct, IJob

    Schedules a job to run once, after every one of has finished.

  • public JobHandle ScheduleParallel<TJob>(in TJob job, int length, int batchSize = 0, JobHandle dependsOn = default(JobHandle)) where TJob : struct, IJobParallelFor

    Schedules indices across the workers.

  • public JobHandle ScheduleParallel<TJob>(in TJob job, int length, int batchSize, ReadOnlySpan<JobHandle> dependsOn) where TJob : struct, IJobParallelFor

    Schedules indices across the workers.

  • public void ParallelFor<TJob>(in TJob job, int length, int batchSize = 0) where TJob : struct, IJobParallelFor

    Runs indices across the workers and waits for them.

  • public void Complete(JobHandle handle)

    Waits for a job, executing other ready work while it waits.

  • public bool IsCompleted(JobHandle handle)

    Whether a job has finished. Never blocks.

  • public void Dispose()

    Stops the workers, draining whatever is still outstanding first.

Used by (31)

  • ProgramEcsStressTest
  • CrowdBenchmarksVixen.Benchmarks.Animation
  • ParallelForBenchmarksVixen.Benchmarks.Jobs
  • PathQueueBenchmarksVixen.Benchmarks.Navigation
  • SchedulingOverheadBenchmarksVixen.Benchmarks.Jobs
  • SweepBenchmarksVixen.Benchmarks.Vfx
  • AnimationSystemVixen.Animation
  • AppBuilderVixen.App.Hosting
  • AppServicesVixen.App.Hosting
  • EcsIntegrationTestsVixen.Animation.Tests
  • EngineLoopVixen.Engine
  • ForkJobVixen.Core.Threading.Tests
  • FrameBudgetTestsVixen.Rendering.Tests
  • GpuVisibilityGroupVixen.Rendering
  • IVisibilityGroupVixen.Rendering
  • JobHandleVixen.Core.Threading
  • JobSchedulerTestsVixen.Core.Threading.Tests
  • NavPathQueueVixen.Navigation
  • NavPathQueueJobTestsVixen.Navigation.Tests
  • NestedJobVixen.Core.Threading.Tests
  • RenderSystemVixen.Rendering
  • SingleThreadedJobSchedulerTestsVixen.Core.Threading.Tests
  • SystemContextVixen.Ecs
  • SystemRunnerVixen.Ecs
  • SystemTestsVixen.Ecs.Tests
  • VfxParallelTestsVixen.Vfx.Tests
  • VfxSimulationVixen.Vfx
  • VfxSystemVixen.Vfx
  • VisibilityGroupVixen.Rendering
  • VisibilityGroupTestsVixen.Rendering.Tests
  • VixenApplicationVixen.App.Hosting