add IterateParallel extension method

This commit is contained in:
Mikhail 2023-06-11 23:18:56 +08:00
parent d4d0a888ca
commit 71bdcaa770
2 changed files with 93 additions and 79 deletions

14
src/EcsGroupExtensions.cs Normal file
View 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);
}
}
}

View File

@ -1,101 +1,101 @@
using DCFApixels.DragonECS;
internal static class ThreadRunner
namespace DCFApixels.DragonECS
{
private readonly static int _maxThreadsCount;
private static ThreadReacord[] _threads;
private static ThreadWorkerHandler _worker;
private static int[] _entities = new int[64];
private static void ThreadProc(object obj)
internal static class ThreadRunner
{
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));
private readonly static int _maxThreadsCount;
private static ThreadReacord[] _threads;
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()
{
_maxThreadsCount = Environment.ProcessorCount;
_threads = new ThreadReacord[_maxThreadsCount];
for (int i = 0; i < _maxThreadsCount; i++)
static ThreadRunner()
{
_threads[i] = new ThreadReacord()
_maxThreadsCount = Environment.ProcessorCount;
_threads = new ThreadReacord[_maxThreadsCount];
for (int i = 0; i < _maxThreadsCount; i++)
{
thread = new Thread(ThreadProc) { IsBackground = true },
runWork = new ManualResetEvent(false),
doneWork = new ManualResetEvent(true),
};
_threads[i].thread.Start(i);
_threads[i] = new ThreadReacord()
{
thread = new Thread(ThreadProc) { IsBackground = true },
runWork = new ManualResetEvent(false),
doneWork = new ManualResetEvent(true),
};
_threads[i].thread.Start(i);
}
_worker = delegate { };
}
_worker = delegate { };
}
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)
public static void Run(ThreadWorkerHandler worker, EcsReadonlyGroup entities, int minSpanSize)
{
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++)
{
ref var thread = ref _threads[i];
thread.start = i * spanSize;
thread.size = spanSize;
thread.runWork.Reset();
thread.runWork.Set();
}
_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++)
{
_threads[i].doneWork.WaitOne();
}
_worker = null;
}
for (int i = 0; i < threadsCount; i++)
private struct ThreadReacord
{
ref var thread = ref _threads[i];
thread.runWork.Reset();
thread.runWork.Set();
}
for (int i = 0; i < threadsCount; i++)
{
_threads[i].doneWork.WaitOne();
}
public Thread thread;
public ManualResetEvent runWork;
public ManualResetEvent doneWork;
_worker = null;
public int start;
public int size;
}
}
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;
}
}