3
3
using Collections . Pooled ;
4
4
using CommunityToolkit . HighPerformance ;
5
5
using Schedulers ;
6
+ using Schedulers . Utils ;
6
7
7
8
// ReSharper disable once CheckNamespace
8
9
namespace Arch . Core ;
@@ -11,12 +12,6 @@ namespace Arch.Core;
11
12
12
13
public partial class World
13
14
{
14
-
15
- /// <summary>
16
- /// A list of <see cref="JobHandle"/> which are pooled to avoid allocs.
17
- /// </summary>
18
- private NetStandardList < JobHandle > JobHandles { get ; }
19
-
20
15
/// <summary>
21
16
/// A cache used for the parallel queries to prevent list allocations.
22
17
/// </summary>
@@ -106,6 +101,7 @@ public void InlineParallelChunkQuery<T>(in QueryDescription queryDescription, in
106
101
{
107
102
var archetypeSize = archetype . ChunkCount ;
108
103
var part = new RangePartitioner ( Environment . ProcessorCount , archetypeSize ) ;
104
+ var parentHandle = SharedJobScheduler . Schedule ( ) ;
109
105
foreach ( var range in part )
110
106
{
111
107
var job = pool . Get ( ) ;
@@ -114,27 +110,58 @@ public void InlineParallelChunkQuery<T>(in QueryDescription queryDescription, in
114
110
job . Chunks = archetype . Chunks ;
115
111
job . Instance = innerJob ;
116
112
117
- var jobHandle = SharedJobScheduler . Schedule ( job ) ;
113
+ var jobHandle = SharedJobScheduler . Schedule ( job , parentHandle ) ;
114
+ SharedJobScheduler . Flush ( jobHandle ) ;
118
115
JobsCache . Add ( job ) ;
119
- JobHandles . Add ( jobHandle ) ;
120
116
}
121
117
122
118
// Schedule, flush, wait, return.
123
- var handle = SharedJobScheduler . CombineDependencies ( JobHandles . AsSpan ( ) ) ;
124
- SharedJobScheduler . Flush ( ) ;
125
- handle . Complete ( ) ;
119
+ SharedJobScheduler . Flush ( parentHandle ) ;
120
+ SharedJobScheduler . Wait ( parentHandle ) ;
126
121
127
122
for ( var index = 0 ; index < JobsCache . Count ; index ++ )
128
123
{
129
124
var job = Unsafe . As < ChunkIterationJob < T > > ( JobsCache [ index ] ) ;
130
125
pool . Return ( job ) ;
131
126
}
132
127
133
- JobHandles . Clear ( ) ;
134
128
JobsCache . Clear ( ) ;
135
129
}
136
130
}
137
131
132
+ /// <summary>
133
+ /// Similar to InlineParallelChunkQuery but instead runs the <see cref="IParallelChunkJobProducer"/> on each chunk in parallel.
134
+ /// This makes it possible to run parallel on chunks that are few, but contain lots of entities.
135
+ /// </summary>
136
+ public JobHandle AdvancedInlineParallelChunkQuery < T > ( in QueryDescription queryDescription , in T innerJob ) where T : struct , IParallelChunkJobProducer
137
+ {
138
+ // Job scheduler needs to be initialized.
139
+ if ( SharedJobScheduler is null )
140
+ {
141
+ throw new ( $ "SharedJobScheduler is missing, assign an instance to { nameof ( World ) } .{ nameof ( SharedJobScheduler ) } . This singleton used for parallel iterations.") ;
142
+ }
143
+
144
+ // Cast pool in an unsafe fast way and run the query.
145
+ var query = Query ( in queryDescription ) ;
146
+ var parentHandle = SharedJobScheduler . Schedule ( ) ;
147
+ foreach ( var archetype in query . GetArchetypeIterator ( ) )
148
+ {
149
+ for ( int i = 0 ; i < archetype . Chunks . Count ; i ++ )
150
+ {
151
+ ref var chunk = ref archetype . Chunks [ i ] ;
152
+ var jobCopy = innerJob ;
153
+ jobCopy . SetChunk ( chunk ) ;
154
+ var job = new ParallelJobProducer < T > ( 0 , chunk . Count , jobCopy , SharedJobScheduler , 1 , true ) ;
155
+ job . GetHandle ( ) . SetParent ( parentHandle ) ;
156
+ job . CheckAndSplit ( ) ;
157
+ SharedJobScheduler . Flush ( job . GetHandle ( ) ) ;
158
+ }
159
+ }
160
+
161
+ SharedJobScheduler . Flush ( parentHandle ) ;
162
+ return parentHandle ;
163
+ }
164
+
138
165
/// <summary>
139
166
/// Finds all matching <see cref="Chunk"/>'s by a <see cref="QueryDescription"/> and calls an <see cref="IChunkJob"/> on them.
140
167
/// </summary>
@@ -156,6 +183,7 @@ public JobHandle ScheduleInlineParallelChunkQuery<T>(in QueryDescription queryDe
156
183
157
184
// Cast pool in an unsafe fast way and run the query.
158
185
var query = Query ( in queryDescription ) ;
186
+ var handle = SharedJobScheduler . Schedule ( ) ;
159
187
foreach ( var archetype in query . GetArchetypeIterator ( ) )
160
188
{
161
189
var archetypeSize = archetype . ChunkCount ;
@@ -170,16 +198,14 @@ public JobHandle ScheduleInlineParallelChunkQuery<T>(in QueryDescription queryDe
170
198
Instance = innerJob
171
199
} ;
172
200
173
- var jobHandle = SharedJobScheduler . Schedule ( job ) ;
174
- JobHandles . Add ( jobHandle ) ;
201
+ var jobHandle = SharedJobScheduler . Schedule ( job , handle ) ;
202
+ SharedJobScheduler . Flush ( jobHandle ) ;
175
203
}
176
204
}
177
205
178
- // Schedule, flush, wait, return.
179
- var handle = SharedJobScheduler . CombineDependencies ( JobHandles . AsSpan ( ) ) ;
180
- SharedJobScheduler . Flush ( ) ;
181
- JobHandles . Clear ( ) ;
182
-
206
+ // flush, wait, return.
207
+ SharedJobScheduler . Flush ( handle ) ;
208
+ SharedJobScheduler . Wait ( handle ) ;
183
209
return handle ;
184
210
}
185
211
}
0 commit comments