Inside the parallel block of my code I reference a thread private variable, tid. tid is assigned in a SECTIONS directive.
However, when I print its value I receive a garbage value inside the parallel block but outside the sections block.
Why do I get a garbage value?
What I know is you usually get a garbage value if you access a variable outside a omp parallel block and not being defined as lastprivate.
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
/* 4 threads, 1 core */
int main (int argc, char *argv[])
{
int nthreads, tid;
/* Fork a team of threads giving them their own copies of variables */
#pragma omp parallel private(tid)
{
#pragma omp sections
{
/* Obtain thread number */
tid = omp_get_thread_num();
printf("Hello World from thread = %d\n", tid);
/* Only master thread does this */
if (tid == 0)
{
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
printf("Inside sections %d \n" ,tid);
}
printf("Out of sections %d \n", tid );
#pragma omp single
{
printf("Inside single block %d \n" , tid);
}
} /* All threads join master thread and disband */
printf("Outside parallel block \n");
}
Below is the output I received:
Hello World from thread = 3
Inside sections 3
Out of sections 0
Inside single block 0
Out of sections 1
Out of sections 3
Out of sections -1078056856
Outside parallel block
Why did tid give that garbage value (-1078056856)?
You should initialize tid before parallel block
To use this its value inside threads declare it as firstprivate(tid) in the pragma omp
Related
I have a use case where I want to run two functions in parallel: the first one contains work that I want to execute in thread 0, and the other contains a "for" loop that I want to share among the remaining 3 threads.
my code is like:
void fct1(){
//do some work1
};
void fct2(){
int p;
#pragma omp for schedule(static)
for (p=start; p < end; p++) {
//do some work2
}
};
int main(){
#pragma omp parallel
{
int tid = omp_get_thread_num();
if (tid==0)
fct1();
if(tid!=0)
fct2();
}
return 0;
}
the problem is that the "omp for" in fct2 hangs because it also waits for thread 0 to execute its part.
Do you have any suggestions?
Thank you.
You can do that with a single (or master if you really want thread 0) pragma. The nowait directive will allow other threads to continue running.
You should use a dynamic scheduling in your for loop as it deals better with a variable number of threads. And if thread 0 has finished its work, it will join the pool.
#include <stdio.h>
#include <omp.h>
#define end 2000
void fct1(){
printf("Hey I am thread %d\n", omp_get_thread_num());
};
void fct2(){
int p;
# pragma omp for schedule(dynamic,128) // adapt chunk size to your problem
for (p=0; p < end; p++) {
printf("%d (%d)\t",p,omp_get_thread_num());
} // all, including thread 0, will be synchronized here
};
int main(){
# pragma omp parallel
{
# pragma omp single nowait
fct1();
fct2();
}
return 0;
}
I'm trying to change the following C source code to static scheduling, but I don't know how it's done. I've tried to staticbefore #pragma omp parallel private(nthreads, tid):
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
int nthreads, tid;
/* Fork a team of threads giving them their own copies of variables */
static #pragma omp parallel private(nthreads, tid) //I tried it here
{
/* Obtain thread number */
tid = omp_get_thread_num();
printf("Hello World from thread = %d\n", tid);
/* Only master thread does this */
if (tid == 0)
{
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
} /* All threads join master thread and disband */
}
What I expect is that thread 0 gets the first chunk, thread 1 the second chunk, and so on. However, it's randomly now as it's dynamically
I'm trying to implement counting semaphores using OpenMP's locking constructs, but I'm running into a problem (the program hangs) when trying to use omp_set_lock() inside a critical region.
I'm testing the implementation with a simple producer-consumer program. This is what I've come up with:
#include <omp.h>
#include <stdio.h>
#define N 50
int semaphore_count = 0;
omp_lock_t semaphore_lock;
int A[N];
void semaphore_increment()
{
int my_id = omp_get_thread_num();
#pragma omp critical
{
printf("[%lf][%d] semaphore_count %d --> %d\n", omp_get_wtime(), my_id,
semaphore_count, semaphore_count + 1);
semaphore_count++;
if(semaphore_count == 1) {
// Semaphore was previously locked, so unlock it.
printf("[%lf][%d] Releasing lock.\n", omp_get_wtime(), my_id);
omp_unset_lock(&semaphore_lock);
}
}
}
void semaphore_decrement()
{
int my_id = omp_get_thread_num();
#pragma omp critical
{
printf("[%lf][%d] semaphore_count: %d\n", omp_get_wtime(), my_id,
semaphore_count);
if (semaphore_count == 0) {
printf("[%lf][%d] Sleeping\n", omp_get_wtime(), my_id);
omp_set_lock(&semaphore_lock);
}
else {
printf("[%lf][%d] Working\n", omp_get_wtime(), my_id);
// Creating a critical region here instead of in the beginning of
// the function solves the problem.
// #pragma omp critical
// {
semaphore_count--;
// }
if (semaphore_count == 0) {
omp_set_lock(&semaphore_lock);
}
}
}
}
void produce() {
for (int i = 0; i < N; ++i) {
A[i] = i;
#pragma omp flush
semaphore_increment();
}
}
void consume() {
int sum = 0;
for (int i = 0; i < N; ++i) {
semaphore_decrement();
sum += A[i];
}
printf("Sum is: %d\n", sum);
}
int main() {
omp_init_lock(&semaphore_lock);
omp_set_lock(&semaphore_lock);
#pragma omp parallel
{
#pragma omp single nowait
produce();
#pragma omp single nowait
consume();
}
omp_destroy_lock(&semaphore_lock);
return 0;
}
This version of the program hangs every time the consumer thread goes to sleep. If I modify it to reduce the critical region to a smaller portion of the code (as indicated by the comment in the program), then it works.
What I don't understand is: why does this happen? It seems that the producer thread, which only increments the semaphore, stops running, and then everything hangs, but I don't understand why.
This answer is WRONG (see the comments). I leave it here as an example of how not to do it.
As noted in the comments by EOF, the program shown in the question is wrong, because it has a race condition regarding the update of the semaphore_count variable, since that can happen simultaneously in two different critical sections.
I ended up replacing functions semaphore_increment and semaphore_decrement by the following function, which can both increment or decrement the semaphore value depending on the value passed in as operation.
void semaphore_update(int operation) {
int my_id = omp_get_thread_num();
int set_lock = 0;
#pragma omp critical
{
if (operation == 0) { // Decrement operation
if (semaphore_count == 0) {
set_lock = 1;
}
else {
semaphore_count--;
if (semaphore_count == 0) {
// Locking here won't actually lock the current thread, only set
// the semaphore so that the *next* thread will be put to sleep.
set_lock = 1;
}
}
}
else { // Increment operation
semaphore_count++;
if(semaphore_count == 1) {
// Semaphore was previously locked, so unlock it.
omp_unset_lock(&semaphore_lock);
}
}
}
// The actual call to omp_set_lock has to happen outside the critical region
// otherwise any threads trying to unlock the semaphore won't be able to
// get access to the critical region.
if (set_lock) {
omp_set_lock(&semaphore_lock);
}
}
I'm tryng to implement following reader-writer problem with reader priority ,So first of all, all the reader threads should execute then remaining writer threads.
#include<omp.h>
#include<semaphore.h>
#include<stdio.h>
#include<unistd.h>
int var=10;
int ReadCount=0;
sem_t Sem;
void main()
{
sem_init(&Sem, 0, 1);
int ThreadId = 0;
int NReader, NWriter;
int i,j;
printf("\nEnter number of readers: ");
scanf("%d",&NReader);
printf("\nEnter number of writers: ");
scanf("%d",&NWriter);
#pragma omp parallel num_threads( (NReader+NWriter) ) shared(ThreadId) /*specifies threadId variable is shared
among all the threads*/
{
printf("\n in parallel construct");
#pragma omp for nowait
for(i=0 ; i<NReader ; i++)
{
printf("\nReader started %d",i);
//sleep(5);
#pragma omp critical
{
ReadCount++;
if(ReadCount==1)
sem_wait(&Sem);
}
ThreadId = omp_get_thread_num();
printf("\n\nReader %d with thread id %d is reading shared variable %d ",i,ThreadId,var);
#pragma omp critical
{
ReadCount--;
if(ReadCount==0)
sem_post(&Sem);
}
// sleep(5);
}
#pragma omp for nowait
for(j=0 ; j<NWriter ; j++)
{
printf("\nWriter started %d",j);
sem_wait(&Sem);
sleep(1);
var=var+2;
ThreadId = omp_get_thread_num();
printf("\nWriter %d with ThreadId %d has updated the shared variable to %d ",j,ThreadId,var);
sem_post(&Sem);
}
}
//end of parallel construct
}
But In output always some writer thread is executing in between . I dont know why it is ocurring ? Please anyone suggest me solution to it.
OUTPUT:
[eshwar#localhost ~]$ gcc -fopenmp readwrit.c
[eshwar#localhost ~]$ ./a.out
Enter number of readers: 3
Enter number of writers: 2
in parallel construct
Reader started 0
Reader 0 with thread id 0 is reading shared variable 10
Writer started 0
in parallel construct
in parallel construct
in parallel construct
Reader started 2
in parallel construct
Reader started 1
Writer 0 with ThreadId 0 has updated the shared variable to 12
Reader 2 with thread id 2 is reading shared variable 12
Reader 1 with thread id 1 is reading shared variable 12
Writer started 1
Writer 1 with ThreadId 1 has updated the shared variable to 14 [eshwar#localhost ~]$
I have a code which solves your problem
#include<stdio.h>
#include <time.h>
#include <unistd.h>
#include <omp.h>
int main()
{
int i=0,NumberofReaderThread=0,NumberofWriterThread;
omp_lock_t writelock;
omp_init_lock(&writelock);
int readCount=0;
printf("\nEnter number of Readers thread(MAX 10)");
scanf("%d",&NumberofReaderThread);
printf("\nEnter number of Writers thread(MAX 10)");
scanf("%d",&NumberofWriterThread);
int tid=0;
#pragma omp parallel
#pragma omp for
for(i=0;i<NumberofReaderThread;i++)
{
// time_t rawtime;
//struct tm * timeinfo;
// time ( &rawtime );
//timeinfo = localtime ( &rawtime );
//printf ( "Current local time and date: %s", asctime (timeinfo) );
//sleep(2);
printf("\nReader %d is trying to enter into the Database for reading the data",i);
omp_set_lock(&writelock);
readCount++;
if(readCount==1)
{
printf("\nReader %d is reading the database",i);
}
omp_unset_lock(&writelock);
readCount--;
if(readCount==0)
{
printf("\nReader %d is leaving the database",i);
}
}
#pragma omp parallel shared(tid)// Specifies that one or more variables should be shared among all threads.
#pragma omp for nowait //If there are multiple independent loops within a parallel region
for(i=0;i<NumberofWriterThread;i++)
{
printf("\nWriter %d is trying to enter into database for modifying the data",i);
omp_set_lock(&writelock);
printf("\nWriter %d is writting into the database",i);
printf("\nWriter %d is leaving the database",i);
omp_unset_lock(&writelock);
}
omp_destroy_lock(&writelock);
return 0;
}
But this is done using lock mechanism . You can find similar steps for semaphores too.
I am trying to use OpenMP for threading as it is cross platform. However I can't work out how to make the code after the parallel continue while the loop is running? It basically just executes the first loop in parallel but never gets to the second non parallel loop?
int main() {
#pragma omp parallel
while(1) {
Sleep(4000);
printf("doing work in thread %d, nthreads %d\n", omp_get_thread_num(), omp_get_num_threads());
}
while (1) {
Sleep(4000);
printf("Hello from main %d, nthreads %d\n", omp_get_thread_num(), omp_get_num_threads());
}
}
I think you could just make one of the threads your special thread within your omp parallel block
int main() {
#pragma omp parallel
if(omp_get_thread_num()==0){
while(1) {
Sleep(4000);
printf("Hello from main %d, nthreads %d\n", omp_get_thread_num(), omp_get_num_threads());
}
}else{
while(1) {
Sleep(4000);
printf("doing work in thread %d, nthreads %d\n", omp_get_thread_num(), omp_get_num_threads());
}
}
}
}
Weather this makes sense in your case is hard to judge without more details.
You could also use sections. Example from here: http://bisqwit.iki.fi/story/howto/openmp/#Sections :
#pragma omp parallel // starts a new team
{
//Work0(); // this function would be run by all threads.
#pragma omp sections // divides the team into sections
{
// everything herein is run only once.
{ Work1(); }
#pragma omp section
{ Work2();
Work3(); }
#pragma omp section
{ Work4(); }
}
//Work5(); // this function would be run by all threads.
}
You can do nested renationalisation: OpenMP: What is the benefit of nesting parallelizations?