# Finding the minimum value in an array

• Example: Find the Minimum value in an array

• When writing a parallel program, you must divide the work into (preferrably) non-overlapping subtasks

• Usually there are many different ways to divide a task into subtasks

(And sometimes, it is not possible to divide the task into non-overlapping tasks and you may have to repeat some steps - necessary evil in parallel programming...

• You may think that dividing the task of "Finding the minimum value" in an array is pretty straighforward - and yet, there are many ways to do so.

Some ways are better than others.

• Let's do a simple example: split the task of "Finding the minimum value" in an array into 2 subtasks (each subtask performed by one thread).

• Split the array into 2 (approximate) equal halfs
• Thread 1 finds the minimum in the first half of the array
• Thread 2 finds the minimum in the second half of the array
• Main thread waits for the results and find the actual minimum.

Pictorially:

 ``` values handled by values handled by thread 0 thread 1 |<--------------------->|<--------------------->| | | | | V V min[0] min[1] \ / \ / \ / \ / \ / main thread | | V Actual minimum ```

In general, the division of the data in the array is as follows

• Create the worker( ) threads (run the function worker( ))

• The main( ) function passes an id to each worker( ) function thread

 0 means: find minimum in array[0 .. n-1] 1 means: find minimum in array[n .. 2n-1] 2 means: find minimum in array[2n .. 3n-1] And so on

• Wait for the worker( ) function to find the minimum in its range

 thread 0 will return the minimum value in variable min[0] thread 1 will return the minimum value in variable min[1] thread 2 will return the minimum value in variable min[2] And so on

• Find the overall minimum among the minimum values min[0], min[1], min[2], ....

C++ code for the main( ) function:

 ``` /* Shared Variables */ double x[1000000]; // Must be SHARED (accessed by worker threads !!) int start[100]; // Contain starting array index of each thread double min[100]; // Contain the minimum found by each thread int num_threads; // ----------------------------------- // Create worker threads.... // ----------------------------------- for (i = 0; i < num_threads; i = i + 1) { start[i] = i; // Pass ID to thread in a private variable if ( pthread_create(&tid[i], NULL, worker, (void *)&start[i]) ) { cout << "Cannot create thread" << endl; exit(1); } } // ----------------------------------- // Wait for worker threads to end.... // ----------------------------------- for (i = 0; i < num_threads; i = i + 1) pthread_join(tid[i], NULL); // ---------------------------------------- // Post processing: Find actual minimum // ---------------------------------------- my_min = min[0]; for (i = 1; i < num_threads; i++) if ( min[i] < my_min ) my_min = min[i]; ```

• Finds the minimum value in its portion of the array

• Recall how the thread s determines its portion of work:

The C++ code for worker( ):

 ``` void *worker(void *arg) { int i, s; int n, start, stop; double my_min; n = MAX/num_threads; // number of elements to handle s = * (int *) arg; // Convert arg to an integer start = s * n; // Starting index if ( s != (num_threads-1) ) { stop = start + n; // Ending index } else { stop = MAX; } my_min = x[start]; for (i = start+1; i < stop; i++ ) // Find min in my range { if ( x[i] < my_min ) my_min = x[i]; } min[s] = my_min; // Store min in private slot return(NULL); /* Thread exits (dies) */ } ```

• Example Program: (Demo above code)

On Solaris compile with: CC -mt min-mt1.C
On Linux compile with: g++ -pthread min-mt1.C

Changes that you need to make to compile on Linux:

```    #include <iostream.h>   ===>   #include <iostream>