// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; using System.Threading.Tasks; namespace SixLabors.ImageSharp.Drawing.Processing.Backends { /// /// Centralizes the conversion from configuration parallelism settings to partition counts and /// instances used by retained-scene CPU execution paths. /// internal static class ParallelExecutionHelper { /// /// Computes the number of partitions to schedule for work constrained by a single work-item limit. /// /// /// The configured maximum degree of parallelism. A value of -1 leaves the runtime /// parallelism cap unbounded, but partition planning remains capped to /// to avoid excessive fan-out. /// /// The total number of work items available for partitioning. /// The number of partitions to schedule. public static int GetPartitionCount(int maxDegreeOfParallelism, int workItemCount) => Math.Min(GetPartitionLimit(maxDegreeOfParallelism), workItemCount); /// /// Computes the number of partitions to schedule for work constrained by two independent limits. /// /// /// The configured maximum degree of parallelism. A value of -1 leaves the runtime /// parallelism cap unbounded, but partition planning remains capped to /// to avoid excessive fan-out. /// /// The total number of work items available for partitioning. /// An additional caller-specific upper bound on useful partitions. /// The number of partitions to schedule. public static int GetPartitionCount(int maxDegreeOfParallelism, int workItemCount, int secondaryLimit) => Math.Min(GetPartitionLimit(maxDegreeOfParallelism), Math.Min(workItemCount, secondaryLimit)); /// /// Creates the for a partitioned operation. /// /// /// The configured maximum degree of parallelism. A value of -1 retains the runtime's /// unbounded sentinel because is always positive; positive /// values are capped to the smaller of the configured limit and the useful partition count. /// /// The computed positive number of useful partitions for the operation. /// The instance for the operation. public static ParallelOptions CreateParallelOptions(int maxDegreeOfParallelism, int partitionCount) => new() { MaxDegreeOfParallelism = Math.Min(maxDegreeOfParallelism, partitionCount) }; /// /// Computes the internal partition-planning cap for the configured parallelism setting. /// /// /// The configured maximum degree of parallelism. A value of -1 keeps the runtime /// parallelism setting unbounded, but partition planning is capped to /// . /// /// The maximum number of partitions to plan for. private static int GetPartitionLimit(int maxDegreeOfParallelism) => maxDegreeOfParallelism == -1 ? Environment.ProcessorCount : maxDegreeOfParallelism; } }