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