23
Jul
0

C++ – OpenMP – Examples of basic parallel programming

You want to start OpenMp ? And you already know how to program in C++? Here is a good extract of code to understand how it works.

#include <omp.h>
#include <cstdio>

/**
* On visual studio : Configuration Properties->C/C++->Language->OpenMP Support
*
* with g++ : -lgomp -fopenmp
*/

/** Example OMP Time */
void CountTime(){
    printf("-------- Simply count elapsed time (CountTime) -------\n");

    const double startTime = omp_get_wtime();

    // Do some stuffs

    const double endTime = omp_get_wtime();

    printf("Duration = %lf seconds", (endTime - startTime));

    printf("--------------------------\n");
}

/** Doing something in parallel */
void DoInParallel(){
    printf("--------  Just create simple thread (DoInParallel) -------\n");

    // Here we do a section in parallel
    #pragma omp parallel
    {
        // Each thread will print :
        printf("Hello I am the thread number %d\n", omp_get_thread_num());
    }

    printf("--------------------------\n");
}

/** To know the number of processes and each ID */
void NumberOfThreadAndIf(){
    printf("-------- Create threads and say how many there are (NumberOfThreadAndIf) -------\n");

    // Each thread prints his ID
    #pragma omp parallel
    {
        printf("Hello I am the thread number %d\n", omp_get_thread_num());
        // Print the number of Threads Now
        printf("We are %d\n", omp_get_num_threads());
    }

    // Print the number of Thread Now = 1
    printf("Out of paralle section, We are %d\n", omp_get_num_threads());

    printf("--------------------------\n");
}

/** Working with a specific number of threads */
void IWantTwoThreads(){
    printf("-------- Specify the number of threads you want (IWantTwoThreads) -------\n");

    printf("We want 2 threads\n");
    // Set the number of thread when we do something in parallel
    omp_set_dynamic( 0 );
    // Doing thing in parallel with a specific number of thread in C
    omp_set_num_threads( 2 );
    // Or usually omp_set_num_threads(omp_num_procs())
    #pragma omp parallel
    {
        printf("Hello I am the thread number %d\n", omp_get_thread_num());
    }

    printf("We want 4 threads\n");
    // Or in Pragma
    #pragma omp parallel num_threads(4)
    {
        printf("Hello I am the thread number %d\n", omp_get_thread_num());
    }

    printf("--------------------------\n");
}

void ShowImplicitBarrier(){
    printf("-------- Use the barrier (ShowImplicitBarrier) -------\n");

    printf("Start working...\n");
    // Each thread waits others at the end of the section
    #pragma omp parallel num_threads(4)
    {
        // Each thread sleeps ID second (master thread sleep 0 s)
        double startTime = omp_get_wtime();
        while( (omp_get_wtime() - startTime) < double(omp_get_thread_num()));
        printf( "Me (%d) I finish to count\n", omp_get_thread_num());
    }
    printf("Master thread is outside the parallel section\n");

    printf("Start working...\n");
    // Threads do not wait each others
    #pragma omp parallel num_threads(4) //nowait
    {
        // Each thread sleeps ID second (master thread sleep 0 s)
        double startTime = omp_get_wtime();
        while( (omp_get_wtime() - startTime) < double(omp_get_thread_num()));
        printf("Me (%d) I finish to count\n", omp_get_thread_num());
    }
    printf("Master thread is outside the parallel section\n");

    printf("--------------------------\n");
}

/** Parallel Switch */
void ShowSection(){
    printf("-------- Show section use case (ShowSection) -------\n");

    // Start Section with number of thread lower than the number of section
    printf("Start with 2 procs\n");
    #pragma omp parallel sections num_threads(2)
    {
        #pragma omp section
        {
            printf("Start work 1\n");
            double startTime = omp_get_wtime();
            while( (omp_get_wtime() - startTime) < 2.0);
            printf("Finish work 1\n");
        }
        #pragma omp section
        {
            printf("Start work 2\n");
            double startTime = omp_get_wtime();
            while( (omp_get_wtime() - startTime) < 2.0);
            printf("Finish work 2\n");
        }
        #pragma omp section
        {
            printf("Start work 3\n");
            double startTime = omp_get_wtime();
            while( (omp_get_wtime() - startTime) < 2.0);
            printf("Finish work 3\n");
        }
    }

    // Start Section with number of thread lower than the upper of section
    printf("Start with 4 procs\n");
    #pragma omp parallel sections num_threads(4)
    {
        #pragma omp section
        {
            printf("Start work 1\n");
            double startTime = omp_get_wtime();
            while( (omp_get_wtime() - startTime) < 2.0);
            printf("Finish work 1\n");
        }
        #pragma omp section
        {
            printf("Start work 2\n");
            double startTime = omp_get_wtime();
            while( (omp_get_wtime() - startTime) < 2.0);
            printf("Finish work 2\n");
        }
        #pragma omp section
        {
            printf("Start work 3\n");
            double startTime = omp_get_wtime();
            while( (omp_get_wtime() - startTime) < 2.0);
            printf("Finish work 3\n");
        }
    }

    printf("--------------------------\n");
}

/** Show For Loop */
void ShowFor(){
    printf("-------- Show for example (ShowFor) -------\n");

    printf("For with normal threads number\n");
    #pragma omp parallel for
    for(int idx = 0 ; idx < 10 ; ++idx){
        printf( "Thread %d works with idx %d\n", omp_get_thread_num(), idx );
    }

    printf("For with normal 4 threads \n");
    // For with number of thread
    omp_set_num_threads( 4 );
    #pragma omp parallel for //num_threads(4)
    for(int idx = 0 ; idx < 10 ; ++idx){
        printf( "Thread %d works with idx %d\n", omp_get_thread_num(), idx );
    }

    // For with an operation after the for
    int sum = 0;
    int dec = 0;
    #pragma omp parallel for reduction(+:sum) reduction(-:dec)
    for(int idx = 0 ; idx < 10 ; ++idx){
        ++sum;
        ++dec;
        printf( "Thread %d sum = %d\n", omp_get_thread_num(), sum );
    }
    printf("Total Sum = %d\n", sum );
    printf("Total Dec = %d\n", dec );

    printf("--------------------------\n");
}

/** Example barrier directives */
void BarrierExample(){
    printf("-------- Example of barrier and work (BarrierExample) -------\n");

    /** Show barrier */
    #pragma omp parallel num_threads(4)
    {
        // Each thread sleep ID second (master thread sleep 0 s)
        double startTime = omp_get_wtime();
        while( (omp_get_wtime() - startTime) < double(omp_get_thread_num()));
        printf("Me (%d)  I finish to count\n", omp_get_thread_num());
        // Each thread will wait other
        #pragma omp barrier
        printf("Barrier passed\n");
    }

    printf("Parallel for ordered\n");
    /** Show ordered */
    #pragma omp parallel for num_threads(4) ordered
    for(int idx = 0 ; idx < 4 ; ++idx)
    {
        // One by one
        #pragma omp ordered
        {
            printf("I am %d\n" , omp_get_thread_num());
            double startTime = omp_get_wtime();
            while( (omp_get_wtime() - startTime) < 2.0);
            printf("Me (%d)  I finish to count\n", omp_get_thread_num());
        }
    }

    printf("single\n");
    /** Show single */
    #pragma omp parallel num_threads(4)
    {
        // Only the first arrived pass
        #pragma omp single
        {
            printf("Single is %d \n", omp_get_thread_num());
        }
        printf("I am %d\n", omp_get_thread_num());
    }

    printf("single nowait\n");
    /** Show single */
    #pragma omp parallel num_threads(4)
    {
        // Only the first arrived pass
        #pragma omp single nowait
        {
            printf("Single is %d \n", omp_get_thread_num());
        }
        printf("I am %d\n", omp_get_thread_num());
    }

    printf("master\n");
    /** Show master */
    #pragma omp parallel num_threads(4)
    {
        // Only master passes
        #pragma omp master
        {
            printf("Master is %d \n", omp_get_thread_num());
        }
        printf("I am %d\n", omp_get_thread_num());
    }

    printf("--------------------------\n");
}

/** Critical section */
void ShowCritical(){
    printf("--------  ShowCritical -------\n");

    /** Show ordered */
    #pragma omp parallel num_threads(4)
    {
        // One by one
        #pragma omp critical
        {
            printf("I am %d\n", omp_get_thread_num());
            double startTime = omp_get_wtime();
            while( (omp_get_wtime() - startTime) < 2.0);
            printf("Me (%d)  I finish to count\n", omp_get_thread_num());
        }
    }

    /** Show atomic */
    int result = 0;
    #pragma omp parallel num_threads(4)
    {
        #pragma omp atomic
        ++result;
    }
    printf("Result %d\n", result);

    printf("--------------------------\n");
}

/** Global variable for next test */
int variableForCriticalSectionSHARED = 0;
int variableForCriticalSectionPRIVATE = 0;
/** Critical section */
void ShowVariablesProtection(){
    printf("--------  ShowVariablesProtection -------\n");

    int variableSHARED = 0;
    int variablePRIVATE = 0;
    /** Show master */
    #pragma omp parallel num_threads(4) shared(variableSHARED,variableForCriticalSectionSHARED) \
            private(variablePRIVATE) //threadprivate(variableForCriticalSectionPRIVATE)
    {
        // Only master pass
        #pragma omp master
        {
            printf("Master is sleeping \n");
            double startTime = omp_get_wtime();
            while( (omp_get_wtime() - startTime) < 4.0);
        }
        if(omp_get_thread_num() != 0){
            printf("num thread %d \n", omp_get_thread_num());
            variableSHARED = omp_get_thread_num();
            variableForCriticalSectionSHARED = omp_get_thread_num();
            variablePRIVATE = omp_get_thread_num();
            variableForCriticalSectionPRIVATE = omp_get_thread_num();
        }
    }

    // Print result - unknow result for shared variables
    printf("variableSHARED = %d\n", variableSHARED);
    printf("variableForCriticalSectionSHARED = %d\n", variableForCriticalSectionSHARED);
    printf("variablePRIVATE = %d\n", variablePRIVATE);
    printf("variableForCriticalSectionPRIVATE = %d\n", variableForCriticalSectionPRIVATE);

    printf("--------------------------\n");
}

int main(int , char* [])
{
    CountTime();
    DoInParallel();
    NumberOfThreadAndIf();
    IWantTwoThreads();
    ShowImplicitBarrier();
    ShowSection();
    ShowFor();
    BarrierExample();
    ShowCritical();
    ShowVariablesProtection();

    return 0;
}

Output :

$ ./test
-------- Simply count elapsed time (CountTime) -------
Duration = 0.000001 seconds--------------------------
--------  Just create simple thread (DoInParallel) -------
Hello I am the thread number 0
Hello I am the thread number 1
--------------------------
-------- Create threads and say how many there are (NumberOfThreadAndIf) -------
Hello I am the thread number 1
Hello I am the thread number 0
We are 2
We are 2
Out of paralle section, We are 1
--------------------------
-------- Specify the number of threads you want (IWantTwoThreads) -------
We want 2 threads
Hello I am the thread number 1
Hello I am the thread number 0
We want 4 threads
Hello I am the thread number 1
Hello I am the thread number 3
Hello I am the thread number 0
Hello I am the thread number 2
--------------------------
-------- Use the barrier (ShowImplicitBarrier) -------
Start working...
Me (0) I finish to count
Me (1) I finish to count
Me (2) I finish to count
Me (3) I finish to count
Master thread is outside the parallel section
Start working...
Me (0) I finish to count
Me (1) I finish to count
Me (2) I finish to count
Me (3) I finish to count
Master thread is outside the parallel section
--------------------------
-------- Show section use case (ShowSection) -------
Start with 2 procs
Start work 1
Start work 2
Finish work 1
Start work 3
Finish work 2
Finish work 3
Start with 4 procs
Start work 1
Start work 2
Start work 3
Finish work 1
Finish work 3
Finish work 2
--------------------------
-------- Show for example (ShowFor) -------
For with normal threads number
Thread 0 works with idx 0
Thread 0 works with idx 1
Thread 1 works with idx 5
Thread 1 works with idx 6
Thread 1 works with idx 7
Thread 1 works with idx 8
Thread 0 works with idx 2
Thread 0 works with idx 3
Thread 0 works with idx 4
Thread 1 works with idx 9
For with normal 4 threads
Thread 1 works with idx 3
Thread 1 works with idx 4
Thread 1 works with idx 5
Thread 2 works with idx 6
Thread 2 works with idx 7
Thread 2 works with idx 8
Thread 0 works with idx 0
Thread 0 works with idx 1
Thread 0 works with idx 2
Thread 3 works with idx 9
Thread 2 sum = 1
Thread 2 sum = 2
Thread 2 sum = 3
Thread 1 sum = 1
Thread 1 sum = 2
Thread 1 sum = 3
Thread 3 sum = 1
Thread 0 sum = 1
Thread 0 sum = 2
Thread 0 sum = 3
Total Sum = 10
Total Dec = 10
--------------------------
-------- Example of barrier and work (BarrierExample) -------
Me (0)  I finish to count
Me (1)  I finish to count
Me (2)  I finish to count
Me (3)  I finish to count
Barrier passed
Barrier passed
Barrier passed
Barrier passed
Parallel for ordered
I am 0
Me (0)  I finish to count
I am 1
Me (1)  I finish to count
I am 2
Me (2)  I finish to count
I am 3
Me (3)  I finish to count
single
Single is 0
I am 3
I am 2
I am 0
I am 1
single nowait
I am 1
I am 3
Single is 2
I am 2
I am 0
master
I am 1
I am 3
I am 2
Master is 0
I am 0
--------------------------
--------  ShowCritical -------
I am 1
Me (1)  I finish to count
I am 3
Me (3)  I finish to count
I am 2
Me (2)  I finish to count
I am 0
Me (0)  I finish to count
Result 4
--------------------------
--------  ShowVariablesProtection -------
Master is sleeping
num thread 1
num thread 3
num thread 2
variableSHARED = 2
variableForCriticalSectionSHARED = 2
variablePRIVATE = 0
variableForCriticalSectionPRIVATE = 2
--------------------------
Enjoyed reading this post?
Subscribe to the RSS feed and have all new posts delivered straight to you.

Comments are closed.

Celadon theme by the Themes Boutique