Parallel,For,c#

Kerim 8/7/2016 0

Parallel For

C#
This code uses a Parallel.For loop to check which numbers in an input array are primes:            

            int[] numbers = {1,2,3,4,5,6,7,8,9};
            bool[] isPrime = new bool[numbers.Length];

            Parallel.For(0, numbers.Length, i =>
            {
                isPrime[i] = numbers[i] >= 2;
                for(int factor = 2; factor * factor <= numbers[i]; factor  )
                {
                    if (numbers[i] % factor == 0)
                    {
                        isPrime[i] = false;
                        break;
                    }
                }
            });

Since multiple threads will be used to evaluate the loop body, this parallel loop will potentially execute faster on a multi-core machine, compared to a corresponding sequential loop. 
DO make sure that the loop body delegate is thread-safe, since it will be called from multiple threads concurrently.
DO verify that the loop body delegate does not make assumptions about the order in which loop iterations will execute. For example, there is no guarantee that a thread will process its partition of input elements in the order in which they appear in the input, even though in the current version it will.
CONSIDER increasing the work done by each iteration in a parallel loop if it is very low. The body of a parallel loop is a delegate, and invoking it incurs some overhead. If the work done by the loop body is very small, the delegate invocation overhead may dominate the running time.

Here is an example of a parallel loop with an inexpensive body:

            int[] arr = {1,2,3,4,5,6,7,8,9};

            Parallel.For(0, arr.Length, i =>
                    {
                        arr[i] = ( int)Math .Sqrt(arr[i]);
                    });
 
In the parallel loop, the overhead of invoking the loop body delegate has a significant impact on the performance. To address this performance issue, we can restructure the loop so that each call of the delegate processes an entire chunk of elements.
To save you the work of breaking up the range into chunks, Partitioner class provides a solution that does this for you:

           int[] arr = {1,2,3,4,5,6,7,8,9};

            Parallel.ForEach(
                Partitioner.Create(0, arr.Length, 1024), range =>
                    {
                        for (int i = range.Item1; i < range.Item2; i  )
                        {
                            arr[i] = ( int)Math .Sqrt(arr[i]);
                        }
                    });
   
Now, instead of invoking the loop body delegate once for each element in the arr array, the delegate only gets invoked once for every 1,024 elements. The delegate now processes the entire range delimited by the Tuple<int,int>. 
 

Report Bug

Please Login to Report Bug

Reported Bugs

Comments

Please Login to Comment

Comments