Reputation: 295
I wonder how below logic can be written using OpenMP:
do_something(Job job, Threads x ... x+b){
if(b<1) // if only one thread is assigned
do_real_work(job); return;
// otherwise, divide the work in two subtasks
// Only one thread executes this:
Divide job into job1 and job2
// Divide the assigned threads into two groups
// and assign the subtasks to them.
// The below two lines should be executed in parallel.
do_something(job1, x ... x+b/2)
do_something(job2, x+b/2 ... x+b)
}
The above workflow by itself is simply divide-and-conquer. I want to divide the work among n threads in a "binary-tree" style. Particularly, I want the program to be able to obtain the # of threads from, say, evn var, and take care of the division recursively. If 4 threads are used, then two levels are executed; If 8 threads are used, then three levels are executed, etc.
I have no idea how one can designate a subset of threads to execute a parallel task in OpenMP. And is it even possible to specify the thread IDs to carry out the task?
Upvotes: 0
Views: 1157
Reputation: 74475
Although it is possible to obtain the thread ID using omp_get_thread_num()
and branch according to this ID, it seems that your problem is more appropriate for being solved using explicit tasks. The maximum number of OpenMP threads as set in the environment variable OMP_NUM_THREADS
could be obtained by calling omp_get_max_threads()
(even outside a parallel region) and the actual number could be obtained by calling omp_get_num_threads()
inside an active region. The parallel code should look something like:
do_something(Job job, Threads x ... x+b){
if(b<1) // if only one thread is assigned
do_real_work(job); return;
// otherwise, divide the work in two subtasks
// Only one thread executes this:
Divide job into job1 and job2
// Divide the assigned threads into two groups
// and assign the subtasks to them.
// The below two lines should be executed in parallel.
#pragma omp task
do_something(job1, x ... x+b/2)
#pragma omp task
do_something(job2, x+b/2 ... x+b)
}
// Call like follows
#pragma omp parallel
{
#pragma omp single
{
b = omp_get_num_threads();
do_something(job, x, b);
}
}
Upvotes: 1