mirror of
https://github.com/DCFApixels/DragonECS-ClassicThreads.git
synced 2025-09-17 19:24:37 +08:00
add IterateParallel extension method
This commit is contained in:
parent
d4d0a888ca
commit
71bdcaa770
14
src/EcsGroupExtensions.cs
Normal file
14
src/EcsGroupExtensions.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public static class EcsGroupExtensions
|
||||||
|
{
|
||||||
|
public static void IterateParallel(this EcsGroup self, ThreadWorkerHandler worker, int minSpanSize)
|
||||||
|
{
|
||||||
|
IterateParallel(self, worker, minSpanSize);
|
||||||
|
}
|
||||||
|
public static void IterateParallel(this EcsReadonlyGroup self, ThreadWorkerHandler worker, int minSpanSize)
|
||||||
|
{
|
||||||
|
ThreadRunner.Run(worker, self, minSpanSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,101 +1,101 @@
|
|||||||
using DCFApixels.DragonECS;
|
namespace DCFApixels.DragonECS
|
||||||
|
|
||||||
internal static class ThreadRunner
|
|
||||||
{
|
{
|
||||||
private readonly static int _maxThreadsCount;
|
internal static class ThreadRunner
|
||||||
private static ThreadReacord[] _threads;
|
|
||||||
|
|
||||||
private static ThreadWorkerHandler _worker;
|
|
||||||
private static int[] _entities = new int[64];
|
|
||||||
|
|
||||||
private static void ThreadProc(object obj)
|
|
||||||
{
|
{
|
||||||
ref ThreadReacord record = ref _threads[(int)obj];
|
private readonly static int _maxThreadsCount;
|
||||||
try
|
private static ThreadReacord[] _threads;
|
||||||
{
|
|
||||||
while (Thread.CurrentThread.IsAlive)
|
|
||||||
{
|
|
||||||
record.runWork.WaitOne();
|
|
||||||
record.runWork.Reset();
|
|
||||||
_worker.Invoke(new ReadOnlySpan<int>(_entities, record.start, record.size));
|
|
||||||
|
|
||||||
record.doneWork.Set();
|
private static ThreadWorkerHandler _worker;
|
||||||
|
private static int[] _entities = new int[64];
|
||||||
|
|
||||||
|
private static void ThreadProc(object obj)
|
||||||
|
{
|
||||||
|
ref ThreadReacord record = ref _threads[(int)obj];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (Thread.CurrentThread.IsAlive)
|
||||||
|
{
|
||||||
|
record.runWork.WaitOne();
|
||||||
|
record.runWork.Reset();
|
||||||
|
_worker.Invoke(new ReadOnlySpan<int>(_entities, record.start, record.size));
|
||||||
|
|
||||||
|
record.doneWork.Set();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
static ThreadRunner()
|
static ThreadRunner()
|
||||||
{
|
|
||||||
_maxThreadsCount = Environment.ProcessorCount;
|
|
||||||
_threads = new ThreadReacord[_maxThreadsCount];
|
|
||||||
|
|
||||||
for (int i = 0; i < _maxThreadsCount; i++)
|
|
||||||
{
|
{
|
||||||
_threads[i] = new ThreadReacord()
|
_maxThreadsCount = Environment.ProcessorCount;
|
||||||
|
_threads = new ThreadReacord[_maxThreadsCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < _maxThreadsCount; i++)
|
||||||
{
|
{
|
||||||
thread = new Thread(ThreadProc) { IsBackground = true },
|
_threads[i] = new ThreadReacord()
|
||||||
runWork = new ManualResetEvent(false),
|
{
|
||||||
doneWork = new ManualResetEvent(true),
|
thread = new Thread(ThreadProc) { IsBackground = true },
|
||||||
};
|
runWork = new ManualResetEvent(false),
|
||||||
_threads[i].thread.Start(i);
|
doneWork = new ManualResetEvent(true),
|
||||||
|
};
|
||||||
|
_threads[i].thread.Start(i);
|
||||||
|
}
|
||||||
|
_worker = delegate { };
|
||||||
}
|
}
|
||||||
_worker = delegate { };
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Run(ThreadWorkerHandler worker, EcsReadonlyGroup entities, int minSpanSize)
|
public static void Run(ThreadWorkerHandler worker, EcsReadonlyGroup entities, int minSpanSize)
|
||||||
{
|
|
||||||
_worker = worker;
|
|
||||||
int entitiesCount = entities.Bake(ref _entities);
|
|
||||||
|
|
||||||
int threadsCount = entitiesCount / minSpanSize;
|
|
||||||
//if (entitiesCount % minSpanSize > 0)
|
|
||||||
// threadsCount++;
|
|
||||||
if (threadsCount > _maxThreadsCount)
|
|
||||||
threadsCount = _maxThreadsCount;
|
|
||||||
|
|
||||||
if (threadsCount > 1)
|
|
||||||
{
|
{
|
||||||
int spanSize = entitiesCount / (threadsCount - 1);
|
_worker = worker;
|
||||||
|
int entitiesCount = entities.Bake(ref _entities);
|
||||||
|
|
||||||
|
int threadsCount = entitiesCount / minSpanSize;
|
||||||
|
//if (entitiesCount % minSpanSize > 0)
|
||||||
|
// threadsCount++;
|
||||||
|
if (threadsCount > _maxThreadsCount)
|
||||||
|
threadsCount = _maxThreadsCount;
|
||||||
|
|
||||||
|
if (threadsCount > 1)
|
||||||
|
{
|
||||||
|
int spanSize = entitiesCount / (threadsCount - 1);
|
||||||
|
for (int i = 0; i < threadsCount; i++)
|
||||||
|
{
|
||||||
|
ref var thread = ref _threads[i];
|
||||||
|
thread.start = i * spanSize;
|
||||||
|
thread.size = spanSize;
|
||||||
|
}
|
||||||
|
_threads[^1].size = entities.Count % (threadsCount - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
threadsCount = 1;
|
||||||
|
ref var thread = ref _threads[0];
|
||||||
|
thread.start = 0;
|
||||||
|
thread.size = entitiesCount;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < threadsCount; i++)
|
for (int i = 0; i < threadsCount; i++)
|
||||||
{
|
{
|
||||||
ref var thread = ref _threads[i];
|
ref var thread = ref _threads[i];
|
||||||
thread.start = i * spanSize;
|
thread.runWork.Reset();
|
||||||
thread.size = spanSize;
|
thread.runWork.Set();
|
||||||
}
|
}
|
||||||
_threads[^1].size = entities.Count % (threadsCount - 1);
|
for (int i = 0; i < threadsCount; i++)
|
||||||
}
|
{
|
||||||
else
|
_threads[i].doneWork.WaitOne();
|
||||||
{
|
}
|
||||||
threadsCount = 1;
|
|
||||||
ref var thread = ref _threads[0];
|
_worker = null;
|
||||||
thread.start = 0;
|
|
||||||
thread.size = entitiesCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < threadsCount; i++)
|
private struct ThreadReacord
|
||||||
{
|
{
|
||||||
ref var thread = ref _threads[i];
|
public Thread thread;
|
||||||
thread.runWork.Reset();
|
public ManualResetEvent runWork;
|
||||||
thread.runWork.Set();
|
public ManualResetEvent doneWork;
|
||||||
}
|
|
||||||
for (int i = 0; i < threadsCount; i++)
|
|
||||||
{
|
|
||||||
_threads[i].doneWork.WaitOne();
|
|
||||||
}
|
|
||||||
|
|
||||||
_worker = null;
|
public int start;
|
||||||
|
public int size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void ThreadWorkerHandler(ReadOnlySpan<int> entities);
|
public delegate void ThreadWorkerHandler(ReadOnlySpan<int> entities);
|
||||||
|
|
||||||
private struct ThreadReacord
|
|
||||||
{
|
|
||||||
public Thread thread;
|
|
||||||
public ManualResetEvent runWork;
|
|
||||||
public ManualResetEvent doneWork;
|
|
||||||
|
|
||||||
public int start;
|
|
||||||
public int size;
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user