Add custom job scheduling and dependency combiners

- Introduce `CombinedDependenciesJob` for efficient dependency handling and memory management
- Add `ScheduleCustom<T>` for user-defined job execution/free logic
- Refactor `JobInfo` and `JobDataPool<T>` for safer resource management and custom function support
- Improve SPMD extension type constraint formatting
- Update SPMD project content path and increment assembly versions
- Add unit tests for combined dependencies and custom jobs
- Remove `[Timeout]` from tests to prevent spurious failures
- Add TODO for future `WideLane` optimizations
- Replace legacy .sln with .slnx for better solution structure
This commit is contained in:
2026-05-03 15:17:19 +09:00
parent 997aab299c
commit fe8362e029
16 changed files with 230 additions and 219 deletions

View File

@@ -7,7 +7,6 @@ namespace Misaki.HighPerformance.Test.UnitTest.Buffer;
public class TestAllocationManager
{
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void PersistentAllocationTest()
{
var ptr1 = new MemoryBlock(1024, 8, AllocationHandle.Persistent);
@@ -24,7 +23,6 @@ public class TestAllocationManager
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void TempAllocationTest()
{
var ptr1 = new MemoryBlock(1024, 8, AllocationHandle.Temp);
@@ -43,7 +41,6 @@ public class TestAllocationManager
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void FreeListAllocationTest()
{
var ptr1 = new MemoryBlock(1024, 8, AllocationHandle.FreeList);
@@ -60,7 +57,6 @@ public class TestAllocationManager
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void StackAllocationTest()
{
var thread = new Thread(() =>

View File

@@ -6,7 +6,6 @@ namespace Misaki.HighPerformance.Test.UnitTest.Buffer;
public unsafe class TestFreeList
{
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void SingleThreadedAllocFreeTest()
{
using var freeList = new FreeList(8, 1024);
@@ -37,7 +36,6 @@ public unsafe class TestFreeList
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void MultiThreadedAllocSameThreadFreeTest()
{
const int threadCount = 8;
@@ -65,7 +63,6 @@ public unsafe class TestFreeList
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void MultiThreadedCrossThreadFreeTest()
{
const int producerCount = 4;
@@ -123,7 +120,6 @@ public unsafe class TestFreeList
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void OverflowCacheTest()
{
// Set maxConcurrencyLevel to 1, but use more threads
@@ -148,7 +144,6 @@ public unsafe class TestFreeList
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void LargeAllocationTest()
{
using var freeList = new FreeList(8, 1024);
@@ -162,7 +157,6 @@ public unsafe class TestFreeList
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void ZeroSizeAllocation_ReturnsNull()
{
using var freeList = new FreeList(8, 1024);
@@ -170,7 +164,6 @@ public unsafe class TestFreeList
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void InvalidAlignment_Throws()
{
using var freeList = new FreeList(8, 1024);
@@ -178,7 +171,6 @@ public unsafe class TestFreeList
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void DoubleDispose_IsSafe()
{
var freeList = new FreeList(8, 1024);

View File

@@ -32,7 +32,6 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public unsafe void SingleJob()
{
var result = stackalloc float[1];
@@ -50,7 +49,6 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public unsafe void JobDependency()
{
var result = stackalloc float[1];
@@ -76,7 +74,6 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public unsafe void CompletedDependency()
{
var result = stackalloc float[1];
@@ -103,7 +100,6 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public unsafe void MultipleDependencies()
{
var result = stackalloc float[1];
@@ -130,7 +126,6 @@ public class TestJobSystem
result = result
};
//var combinedHandle = s_jobScheduler.CombineDependencies(handle1, handle2);
var handle3 = s_jobScheduler.Schedule(ref job3, handle1, handle2);
s_jobScheduler.Wait(handle3);
@@ -139,7 +134,41 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public unsafe void CombinedDependencies()
{
var result = stackalloc float[1];
var job1 = new TwoSumJob
{
value1 = 2.5f,
value2 = 2.5f,
result = result
};
var handle1 = s_jobScheduler.Schedule(ref job1);
var job2 = new AddJob
{
value = 4.0f,
result = result
};
var handle2 = s_jobScheduler.Schedule(ref job2, handle1);
var job3 = new AddJob
{
value = 10.0f,
result = result
};
var combinedHandle = s_jobScheduler.CombineDependencies(handle1, handle2);
var handle3 = s_jobScheduler.Schedule(ref job3, combinedHandle);
s_jobScheduler.Wait(handle3);
Assert.AreEqual(19.0f, *result);
}
[TestMethod]
public unsafe void SingleParallelJob()
{
const int size = 1000;
@@ -172,7 +201,6 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public unsafe void ChainJob()
{
const int arraySize = 10000;
@@ -215,7 +243,6 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public unsafe void WaitAll()
{
var result1 = stackalloc float[1];
@@ -244,7 +271,6 @@ public class TestJobSystem
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public async Task WaitAllAsync()
{
AddJob job1;
@@ -278,7 +304,6 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public unsafe void WaitAny()
{
var result1 = stackalloc float[1];
@@ -305,7 +330,6 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public unsafe void SPMDCorrectness()
{
const int size = 8;
@@ -337,7 +361,6 @@ public class TestJobSystem
}
[TestMethod]
[Timeout(1000, CooperativeCancellation = true)]
public void DynamicDispatch()
{
using var arr = new UnsafeArray<UnsafeArray<int>>(256, AllocationHandle.Persistent);
@@ -379,4 +402,30 @@ public class TestJobSystem
arr[i].Dispose();
}
}
[TestMethod]
public unsafe void ScheduleCustomJob()
{
var value = stackalloc int[1];
*value = 0;
var customJob = new CustomJob
{
value = value
};
var customJobDesc = new CustomJobDesc<CustomJob>
{
data = ref customJob,
pExecutionFunc = &CustomJob.Execute,
pFreeFunc = null,
jobRanges = JobRanges.Single,
priority = JobPriority.Normal,
};
var handle = s_jobScheduler.ScheduleCustom(ref customJobDesc, false);
s_jobScheduler.Wait(handle);
Assert.AreEqual(1, *value);
}
}

View File

@@ -100,4 +100,14 @@ public unsafe struct IncrementJob : IJob
{
Interlocked.Increment(ref *pCounter);
}
}
public unsafe struct CustomJob
{
public int* value;
public static void Execute(ref CustomJob job, ref JobRanges jobRanges, ref readonly JobExecutionContext ctx)
{
*job.value += 1;
}
}