1

I'm learning OpenMP these days and I just met the "threadprivate" directive. The code snippet below written by myself didn't output the expected result:

// **** File: fun.h **** //
void seed(int x);
int drand();
// ********************* //

// **** File: fun.c **** //
extern int num;
int drand()
{
    num = num + 1;
    return num;
}
void seed(int num_initial)
{
    num = num_initial;
}
// ************************ //

// **** File: main.c **** //
#include  "fun.h"
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

int num = 0;
#pragma omp threadprivate(num)

int main()
{
    int num_inital = 4;


    seed(num_inital);
    printf("At the beginning, num = %d\n", num);  // should num be 4?
#pragma omp parallel for num_threads(2) schedule(static,1) copyin(num)
    for (int ii = 0; ii < 4; ii++) {    
        int my_rank = omp_get_thread_num();
        //printf("Before processing, in thread %d num = %d\n", my_rank,num);
        int num_in_loop = drand();
        printf("Thread %d is processing loop %d: num = %d\n", my_rank,ii, num_in_loop);
    }

    system("pause");
    return 0;
}
// ********************* //

Here list my questions:

  1. Why the result of printf("At the beginning, num = %d\n", num); is num = 0 instead of num = 4?

  2. As for the parallel for loop, multiple executions produce different results one of which is:

Thread 1 is processing loop 1: num = 5
Thread 0 is processing loop 0: num = 6
Thread 1 is processing loop 3: num = 7
Thread 0 is processing loop 2: num = 8

It seems that num is initialized to 4 in the for loop which denotes that the num in copyin clause is equal to 4. Why num in printf("At the beginning, num = %d\n", num) is different from that in copyin?

  1. In OpenMP website, it said

    In parallel regions, references by the master thread will be to the copy of the variable in the thread that encountered the parallel region.

    According to this explanation, Thread 0 (the master thread) should firstly contains num = 4. Therefore, loop 0's output should always be: Thread 0 is processing loop 0: num = 5. Why the result above is different?

My working environment is win10 operating system with VS2015.

2 Answers 2

1

I think the problem is within the fun.c compilation unit. The compiler cannot determine the extern int num; variable is also a TLS one.

I will include directive #pragma omp threadprivate(num) in this file:

// **** File: fun.c **** //
extern int num;
#pragma omp threadprivate(num)
int drand()
{
    num = num + 1;
    return num;
}
void seed(int num_initial)
{
    num = num_initial;
}
// ************************ //

In any case, the compiler should warn about it at the linking phase.

Sign up to request clarification or add additional context in comments.

Comments

0

The copyin clause is meant to be used in OpenMP teams (eg. computation on computing accelerators).

Indeed, the OpenMP documentation says:

These clauses support the copying of data values from private or threadprivate variables on one implicit task or thread to the corresponding variables on other implicit tasks or threads in the team.

Thus, in you case, you should rather use the clause firstprivate.

Please note that the version (5.0) of the OpenMP documentation your are reading is probably not supported by VS2015. I advise you to read an older version compatible with VS2015. The results of the compiled program are likely to be undefined.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.