Exercise: Partitioner on Find Smallest

In this exercise you will try to use a Partitioner with Parallel.ForEach.

In an earlier exercise you used a number of threads to find the smallest number in a number of arrays.

In this exercise you have to find the smallest number in a single (large) array.

Study

Read and understand the example Gaston Hillar, Professional Parallel Programming with C#, chapter 2, example 2_11, the method ParallelPartitionGenerateAESKeys()

Getting ready

Create a new Solution in Visual Studio. Name the Solution "FindSmallestPartition".

copy this program into your solution:

class Program
  {
    private static readonly int[] Data = { 3, 4, 34, 22, 34, 3, 4, 4, 2, 7, 3, 8, 122, -1, -3, 1, 2 };

    private static int FindSmallest(IList<int> numbers)
    {
        if (numbers.Count == 0)
        {
          throw new ArgumentException("There must be at least one element in the array");
        }
        int smallestSoFar = numbers[0];
        foreach (int number in numbers)
        {
            if (number < smallestSoFar)
            {
              smallestSoFar = number;
            }
         }
        //Console.WriteLine(String.Join("; ", numbers) + ": " + smallestSoFar);
        return smallestSoFar;
    }

     private static void main() {
       1. partition
       2. for each partition find the smallest element and add to ConcurrentBag
       3. find the smallest element in the ConcurrentBag
}

The exercise as such

The idea is to use a Partitioner to divide the array into a number of partitions. For each part of the array we find the smallest number (in a thread) - this and add this number to a thread safe collection (like ConcurrentBag). From this thread safe collection we then find the smallest number.

By dividing the array (or rather the array indeces) into a number of partitions and run each of them in a separate thread, we can use the cores that is on the computer.

Hint: Convert the int[] arrray into a List<int>.

Hint 2: List<int> has a method GetRange(startIndex, length), i.e. GetRange(range.Item1, range.Item2 - range.Item1). This method return a sub-list or the original list.