I have this parallel for loop
struct p
{
int n;
double *l;
}
#pragma omp parallel for default(none) private(i) shared(p)
for (i = 0; i < p.n; ++i)
{
DoSomething(p, i);
}
Now, it is possible that inside DoSomething(), p.n is increased because new elements are added to p.l. I’d like to process these elements in a parallel fashion. OpenMP manual states that parallel for can’t be used with lists, so DoSomething() adds these p.l‘s new elements to another list which is processed sequentially and then it is joined back with p.l. I don’t like this workaround. Anyone knows a cleaner way to do this?
A construct to support dynamic execution was added to OpenMP 3.0 and it is the
taskconstruct. Tasks are added to a queue and then executed as concurrently as possible. A sample code would look like this:This will spawn a new parallel region. One of the threads will execute the
forloop and create a new OpenMP task for each value ofi. Each differentDoSomething()call will be converted to a task and will later execute inside an idle thread. There is a problem though: if one of the tasks add new values top.l, it might happen after the creator thread has already exited theforloop. This could be fixed using task synchronisation constructs and an outer loop like this:The
taskwaitconstruct makes for the thread to wait until all queued tasks are executed. If new elements were added to the list, the condition of thewhilewould become true again and a new round of tasks creation will happen. Theflushconstruct is supposed to synchronise the memory view between threads and e.g. update optimised register variables with the value from the shared storage.OpenMP 3.0 is supported by all modern C compilers except MSVC, which is stuck at OpenMP 2.0.