Home > Software design >  one strange problem when I generate random numbers by OMP(C )
one strange problem when I generate random numbers by OMP(C )

Time:11-15

The code is as follows:

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

int main()
{
    unsigned int seed = 1;
    int n =4;
    int i = 0;
#pragma omp parallel for num_threads(4) private(seed)
    for(i=0;i<n;i  )
    {
        int temp1 = rand_r(&seed);
        printf("\nRandom number: %d by thread %d\n", temp1, omp_get_thread_num());
    }
    return 0;
}

The code output is:

Random number: 1905891579 by thread 0

Random number: 1012484 by thread 1

Random number: 1012484 by thread 2

Random number: 1012484 by thread 3

This is strange for me: why thread 0 has different number? But when I change n with a const number 4:

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

int main()
{
    unsigned int seed = 1;
    const int n =4;
    int i = 0;
#pragma omp parallel for num_threads(4) private(seed)
    for(i=0;i<n;i  )
    {
        int temp1 = rand_r(&seed);
        printf("\nRandom number: %d by thread %d\n", temp1, omp_get_thread_num());
    }
    return 0;
}

The code output is:

Random number: 1012484 by thread 2

Random number: 1012484 by thread 3

Random number: 1012484 by thread 0

Random number: 1012484 by thread 1

All threads have the same random numbers. I don't understand the reason that thread 0 has different number when n is not a const variable. Is there any one know this thing? Thanks a lot.

CodePudding user response:

seed is declared private, so within loop it got no initialized value, more of, each instance may or may not have distinct value, use of its value is UB. You can use firstprivate.

Also rand_r is not a standard function but a level 2 thread-safe POSIX function. Level 2 implies that rand_r is safe only if used on separate objects/sources of data which isn't the case here i you would use same seed counter. The order of thread being called is undetermined and unsynced in this case. Odder outputs are possible because any one of thread may chance to update value of seed before others.

CodePudding user response:

The problem is that the variable declared private is not initialized. If you add this line

  printf("thread %d seed %u \n", omp_get_thread_num(), seed);

before int temp1 = rand_r(&seed) you will get an output like this:

thread 3 seed 0 

Random number: 1012484 by thread 3 seed 2802067423

thread 0 seed 21850 

Random number: 2082025184 by thread 0 seed 2464192641

thread 2 seed 0 

Random number: 1012484 by thread 2 seed 2802067423

thread 1 seed 0 

Random number: 1012484 by thread 1 seed 2802067423

Repeating the runs, on my machine I see that the thread 0 gets always a different seed value, whereas the other threads have seed=0. In any case, this is UB due to an uninitialized variable.

CodePudding user response:

My program uses srand() to get different random values:

const int n = 4;

srand(time(0));
omp_set_num_threads(4);

#pragma omp parallel for num_threads(4) 
for(int i = 0; i<n; i  )
{
    printf("Random number: %d\t Thread: %d\n", rand(), omp_get_thread_num());
}

output:

Random number: 1959537764    Thread: 0
Random number: 1445758023    Thread: 3
Random number: 735503363     Thread: 1
Random number: 977892027     Thread: 2

example

  •  Tags:  
  • c
  • Related