0
votes

Hi, I have written an MPI quicksort program which works like this:

In my cluster 'Master' will divide the integer data and send these to 'Slave nodes'. Upon receiving at the Slave nodes, each slave will perform individual sorting operations and send the sorted data back to Master. Now my problem is I'm interested in introducing hyper-threading for the slaves.

I have data coming from master

  1. sub (which denotes the array)
  2. count (size of an array)

Now I have initialized Pthreads as where

 num_threads=12.
    pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  for (i = 0; i < num_pthreads; i++) {
    if (pthread_create(&thread[i], &attr, new_thread, (void *) &sub[i])) 
    {
       printf("error creating a new thread \n");
       exit(1);
    }
    else
    {
        printf(" threading is successful %d  at node %d \n \t ",i,rank);
    }       

and in a new thread function

void * new_thread(int *sub)
{

    quick_sort(sub,0, count-1);
    }
    return(0);
}

I don't understand whether my way is correct or not. Can anyone help me with this problem?

2

2 Answers

0
votes

Your basic idea is correct, except you also need to determine how you're going to get results back from the threads.

Normally you would want to pass all relevant information for the thread to complete its task through the *arg argument from pthread_create. In your new_thread() function, the count variable is not passed in to the function and so is global between all threads. A better approach is to pass a pointer to a struct through from pthread_create.

typedef struct {
    int *sub; /* Pointer to first element in array to sort, different for each thread. */
    int count; /* Number of elements in sub. */
    int done; /* Flag to indicate that sort is complete. */
} thread_params_t


void * new_thread(thread_params_t *params)
{
   quick_sort(params->sub, 0, params->count-1); 
   params->done = 1;
   return 0;
}

You would fill in a new thread_params_t for each thread that was spawned.

The other item that has to be managed is the sort results. It would be normal for the main thread to do a pthread_join on each thread which ensure that it has completed before continuing. Depending on your requirements you could either have each thread send results back to the master directly, of have the main function collect the results from each thread and send results back external to the worker threads.

0
votes

You can use OpenMP instead of pthreads (just for the record - combining MPI with threading is called hybrid programming). It is a lightweight set of compiler pragmas that turn sequential code into parallel one. Support for OpenMP is available in virtually all modern compilers. With OpenMP you introduce the so-called parallel regions. A team of threads is created at the beginning of the parallel region, then the code continues to execute concurrently until the end of the parallel region, where all threads are joined and only the main thread continues execution (thread creation and joining is logical, e.g. it doesn't have to be implemented like this in real life and most implementations actually use thread pools to speed up the creation of threads):

#pragma omp parallel
{
   // This code gets executed in parallel
   ...
}

You can use omp_get_thread_num() inside the parallel block to get the ID of the thread and make it compute something different. Or you can use one of the worksharing constructs of OpenMP like for, sections, etc. to make it divide the work automatically.

The biggest advantage of OpenMP is that is doesn't introduce deep changes to the source code and it abstracts threads creation/joining away so you don't have to do it manually. Most of the time you can get around with just a few pragmas. Then you have to enable OpenMP during compilation (with -fopenmp for GCC, -openmp for Intel compilers, -xopenmp for Sun/Oracle compilers, etc.). If you do not enable OpenMP or the particular compiler doesn't support it, you'll get a serial program.

You can find a quick but comprehensive OpenMP tutorial at LLNL.