static void SolveVelocityConstraintsCallback(object state) { var svcState = (SolveVelocityConstraintsState)state; svcState.ContactSolver.SolveVelocityConstraints(svcState.Start, svcState.End); SolveVelocityConstraintsState.Return(svcState); Interlocked.Decrement(ref svcState.ContactSolver.SolveVelocityConstraintsWaitLock); }
static void SolveVelocityConstraintsCallback(object state) { var svcState = (SolveVelocityConstraintsState)state; svcState.ContactSolver.SolveVelocityConstraints(svcState.Start, svcState.End); SolveVelocityConstraintsState.Return(svcState); svcState.ContactSolver.SolveVelocityConstraintsWaitLock.Signal(); }
internal static object Get(ContactSolver contactSolver, int start, int end) { SolveVelocityConstraintsState result; if (!_queue.TryDequeue(out result)) { result = new SolveVelocityConstraintsState(); } result.ContactSolver = contactSolver; result.Start = start; result.End = end; return(result); }
public void SolveVelocityConstraints() { if (_count >= _velocityConstraintsMultithreadThreshold && System.Environment.ProcessorCount > 1) { if (_count == 0) { return; } var batchSize = (int)Math.Ceiling((float)_count / System.Environment.ProcessorCount); var batches = (int)Math.Ceiling((float)_count / batchSize); #if NET40 || NET45 || NETSTANDARD2_0 SolveVelocityConstraintsWaitLock.Reset(batches); for (int i = 0; i < batches; i++) { var start = i * batchSize; var end = Math.Min(start + batchSize, _count); ThreadPool.QueueUserWorkItem(SolveVelocityConstraintsCallback, SolveVelocityConstraintsState.Get(this, start, end)); } // We avoid SolveVelocityConstraintsWaitLock.Wait(); because it spins a few milliseconds before going into sleep. Going into sleep(0) directly in a while loop is faster. while (SolveVelocityConstraintsWaitLock.CurrentCount > 0) { Thread.Sleep(0); } #elif PORTABLE40 || PORTABLE45 || W10 || W8_1 || WP8_1 Parallel.For(0, batches, (i) => { var start = i * batchSize; var end = Math.Min(start + batchSize, _count); SolveVelocityConstraints(start, end); }); #else SolveVelocityConstraints(0, _count); #endif } else { SolveVelocityConstraints(0, _count); } return; }
public void SolveVelocityConstraints() { if (_count >= Settings.VelocityConstraintsMultithreadThreshold && System.Environment.ProcessorCount > 1) { if (_count == 0) { return; } var batchSize = (int)Math.Ceiling((float)_count / System.Environment.ProcessorCount); var batches = (int)Math.Ceiling((float)_count / batchSize); #if NET40 || NET45 SolveVelocityConstraintsWaitLock = batches; for (int i = 0; i < batches; i++) { var start = i * batchSize; var end = Math.Min(start + batchSize, _count); ThreadPool.QueueUserWorkItem(SolveVelocityConstraintsCallback, SolveVelocityConstraintsState.Get(this, start, end)); } while (SolveVelocityConstraintsWaitLock > 0) { Thread.Sleep(0); } #elif PORTABLE40 || PORTABLE45 || W10 || W8_1 || WP8_1 Parallel.For(0, batches, (i) => { var start = i * batchSize; var end = Math.Min(start + batchSize, _count); SolveVelocityConstraints(start, end); }); #else SolveVelocityConstraints(0, _count); #endif } else { SolveVelocityConstraints(0, _count); } return; }