Parallel Programming in C with OpenMP

OpenMP – Open Specifications for Multi Processing

The central theme of parallel code is that of threads. A serial code starts off as one thread. As soon as the first parallel directive(Fortran)/pragma(C) is encountered, the master thread forks into a number of threads. The proceeding code is then executed in parallel in a manner which can be adjusted using certain options.

To get started with OpenMP. You will need to include the omp header file with
#include <omp.h>
and you will need to add the -fopenmp option when compiling.

To fork the master thread into a number of parallel threads, one writes the following line of code:
#pragma omp parallel
This directive will apply to the following block of code, {…}, only and must be structured as such. By default, all variables previously declared are shared i.e. all threads have the same memory address of a shared variable. This can, however, be declared explicitly by adding shared(var_name). Conversely, you may want to make variables private, that is, each thread gets allocated a unique location in the memory to store this variable. Private variables are only accessed by the threads they are in and all the additional copies of the variable created for parallisation are destroyed when the threads merge. There are also reduction variables. More on that later…

Lets try an example. When you execute your code, it will inherit the OMP_NUM_THREADS environment variable of your terminal. Suppose we want to set the number of threads to 4. We write

prog@michael-laptop:~$ export OMP_NUM_THREADS=4
prog@michael-laptop:~$ echo $OMP_NUM_THREADS
4
prog@michael-laptop:~$ 

You can also specify the number of threads during run time with the omp_set_num_threads() function defined in omp.h

Good. Now here’s our sample code:

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

int main(void){
printf("Number of threads before parallisation: %d\n",omp_get_num_threads());
#pragma omp parallel 
{
printf("Current thread number: %d\n",omp_get_thread_num());
if(omp_get_thread_num()==0)
{
printf("Number of threads after parallisation: %d\n",omp_get_num_threads());
}
}
printf("Number of threads after merging threads %d\n",omp_get_num_threads());
}

compile and run:

prog@michael-laptop:~$ g++ openmp.cpp -o test -fopenmp
prog@michael-laptop:~$ ./test
Number of threads before parallisation: 1
Current thread number: 3
Current thread number: 1
Current thread number: 0
Number of threads after parallisation: 4
Current thread number: 2
Number of threads after merging threads 1

Next I’ll talk about work sharing…