public static unsafe void GetJobRange(ref JobRanges ranges, int jobIndex, out int beginIndex, out int endIndex) { int *startEndIndices = (int *)ranges.StartEndIndex; beginIndex = startEndIndices[jobIndex * 2]; endIndex = startEndIndices[jobIndex * 2 + 1]; }
public unsafe static void GetJobRange(ref JobRanges ranges, int jobIndex, out int beginIndex, out int endIndex) { int *ptr = (int *)((void *)ranges.StartEndIndex); beginIndex = ptr[jobIndex * 2]; endIndex = ptr[jobIndex * 2 + 1]; }
// TODO: Currently, the actual work stealing code sits in (big) Unity's native code w/ some dependencies // For now, let's simply split the work for each thread over the number of job threads public static bool GetWorkStealingRange(ref JobRanges ranges, int jobIndex, out int begin, out int end) { #if UNITY_SINGLETHREADED_JOBS // IndicesPerPhase is used as a "done" flag. bool done = ranges.IndicesPerPhase == 0; begin = 0; end = ranges.ArrayLength; ranges.IndicesPerPhase = 0; return(!done); #else begin = jobIndex * ranges.IndicesPerPhase; end = Math.Min(begin + ranges.IndicesPerPhase, ranges.ArrayLength); ranges.IndicesPerPhase = 0; return(begin < end); #endif }
// TODO: Currently, the actual work stealing code sits in (big) Unity's native code w/ some dependencies // This is implemented trying to use the same code pattern: // while (true) // { // if (!JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out int begin, out int end)) // break; public static bool GetWorkStealingRange(ref JobRanges ranges, int jobIndex, out int begin, out int end) { if (ranges.State == WorkStealingState.Done) { begin = 0; end = 0; return(false); } #if !UNITY_SINGLETHREADED_JOBS if (ranges.runOnMainThread > 0) { #endif // There's only one thread, and the IndicesPerPhase don't have much meaning. // Do everything in one block of work. begin = 0; end = ranges.ArrayLength; ranges.State = WorkStealingState.Done; return(end > begin); #if !UNITY_SINGLETHREADED_JOBS } // Divide the work equally. // TODO improve by accounting for the indices per phase. int nWorker = JobWorkerCount > 0 ? JobWorkerCount : 1; begin = jobIndex * ranges.ArrayLength / nWorker; end = (jobIndex + 1) * ranges.ArrayLength / nWorker; if (end > ranges.ArrayLength) { end = ranges.ArrayLength; } if (jobIndex == nWorker - 1) { end = ranges.ArrayLength; } ranges.State = WorkStealingState.Done; return(end > begin); #endif }
public static extern bool GetWorkStealingRange(ref JobRanges ranges, int jobIndex, out int beginIndex, out int endIndex);
static extern unsafe void invoke_managed_job_execute_function(IntPtr functionPointer, void *payLoad, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex);
public static bool GetWorkStealingRange(ref JobRanges ranges, int jobIndex, out int begin, out int end) => throw new NotImplementedException();