/// <summary> /// Executes a serial for loop. /// </summary> /// <param name="i0">The start index (inclusive).</param> /// <param name="i1">The end index (exclusive).</param> /// <param name="action">The action that is invoked once per iteration.</param> private static void SerialFor(int i0, int i1, Alt.Action <int> action) { for (int i = i0; i < i1; i++) { action(i); } }
/// <summary> /// Executes a parallel for loop using ThreadPool. /// </summary> /// <param name="i0">The start index (inclusive).</param> /// <param name="i1">The end index (exclusive).</param> /// <param name="action">The action that is invoked once per iteration.</param> private static void ParallelFor(int i0, int i1, Alt.Action <int> action) { // Environment.ProcessorCount is not available here. Use 4 processors. int p = 4; // Initialize wait handles var doneEvents = new System.Threading.WaitHandle[p]; for (int i = 0; i < p; i++) { doneEvents[i] = new System.Threading.ManualResetEvent(false); } // Invoke the action of a partition of the range Alt.Action <int, int, int> invokePartition = (k, j0, j1) => { for (int i = j0; i < j1; i++) { action(i); } ((System.Threading.ManualResetEvent)doneEvents[k]).Set(); }; // Start p background threads int n = (i1 - i0 + p - 1) / p; for (int i = 0; i < p; i++) { int k = i; int j0 = i0 + (i * n); var j1 = Math.Min(j0 + n, i1); System.Threading.ThreadPool.QueueUserWorkItem(state => invokePartition(k, j0, j1)); } // Wait for the threads to finish foreach (var wh in doneEvents) { wh.WaitOne(); } }