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; }