Using OpenMP with C++11 range-based for loops?
Solution 1
OpenMP 5.0 adds the following line on page 99, which makes a lot of range-based for loops OK !
2.12.1.3 A range-based for loop with random access iterator has a canonical loop form.
Source : https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5.0.pdf
Solution 2
The OpenMP 4.0 specification was finalised and published several days ago here. It still mandates that parallel loops should be in the canonical form (§2.6, p.51):
for (
init-expr;
test-expr;
incr-expr)
structured-block
The standard allows for containers that provide random-access iterators to be used in all of the expressions, e.g.:
#pragma omp parallel for
for (it = v.begin(); it < v.end(); it++)
{
...
}
If you still insist on using the C++11 syntactic sugar, and if it takes a (comparatively) lot of time to process each element of stl_container
, then you could use the single-producer tasking pattern:
#pragma omp parallel
{
#pragma omp single
{
for (auto x : stl_container)
{
#pragma omp task
{
// Do something with x, e.g.
compute(x);
}
}
}
}
Tasking induces certain overhead so it would make no sense to use this pattern if compute(x);
takes very little time to complete.
Related videos on Youtube
![Jean-Michaël Celerier](https://i.stack.imgur.com/tDNEB.jpg?s=256&g=1)
Jean-Michaël Celerier
I enjoy coding :) about me: https://jcelerier.name ossia.io CTO (https://ossia.io) celtera.dev (consulting: https://celtera.dev)
Updated on February 22, 2020Comments
-
Jean-Michaël Celerier over 4 years
Is there any counter-indication to doing this ? Or is the behavior well specified?
#pragma omp parallel for for(auto x : stl_container) { ... }
Because it seems that OpenMP specification is only valid for c++98 but I guess there might be more incompatibilities due to C++11 threads, which are not used here. I wanted to be sure, still.
-
lulyon almost 11 years+ Good question. Want to know that, too.
-
-
DarioP almost 11 yearsI think that iterators are the way to go by now, but if you want your code to compile with gcc you need to substitute != with < otherwise you get an "invalid controlling predicate" error. By the way, do you know why?
-
Jean-Michaël Celerier almost 11 yearsAccording to this website : cplusplus.com/reference/iterator/RandomAccessIterator it should work...
-
DarioP almost 11 yearsIn that website they don't put any pragma before the cycle. Just try to compile it :)
-
Hristo Iliev almost 11 years@DarioP, the
!=
is an Intel-ism - the standard does not allow it to be used, buticpc
is smart enough to deduce what's going on in the loop. I had it corrected. That's also one of the reasons why random-access iterators are required - the usual iterators only provide the==
and!=
operators. -
Michael Klemm over 5 yearsOpenMP 5.0 also provides initial support for C++14 and C++17. Not all of the features in those base language are supported, however.
-
oarfish over 3 yearsIt seems that at least with apple clang 12.0.0,
std::map
has no random access iter, so the<
relation doesnt work.