When I use cancel
directive (since OpenMP 4.0) to break parallel loop within parallel for
construct, GCC 5.1 warns "'#pragma omp cancel for' inside 'nowait' for construct" for the following snippet.
const int N = 10000;
int main()
{
#pragma omp parallel for
for (int i = 0; i < N; i++) {
#pragma omp cancel for // <-- here
}
}
http://coliru.stacked-crooked.com/a/de5c52da5a16c154
For workaround, when I split to parallel
+ for
constructs, GCC accepts the code silently.
int main()
{
#pragma omp parallel
#pragma omp for
for (int i = 0; i < N; i++) {
#pragma omp cancel for
}
}
But I don't know why GCC warns the former case, nevertheless the construct has no 'nowait' clause.
OpenMP 4.0 API spec also says that parallel for
is equal to parallel
+ for
constructs.
2.10.1 Parallel Loop Construct
Description
The semantics are identical to explicitly specifying a
parallel
directive immediately followed by afor
directive.
Is GCC's behavior correct? or something wrong?
My guess is that your code
#pragma omp parallel for
for (int i = 0; i < N; i++) {
#pragma omp cancel for
}
is not equivalent to
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < N; i++) {
#pragma omp cancel for
}
} //end of parallel region
in the latter case, there would be two barriers: one at the end of the for and one at the end of the parallel region; something equivalent to:
#pragma omp parallel
{
#pragma omp for nowait
for (int i = 0; i < N; i++) {
#pragma omp cancel for
}
#pragma omp barrier
} // and here another implicit barrier
but I guess that for optimization purpose, the compilter may try to remove the second unecessary barrier and generates:
#pragma omp parallel
{
#pragma omp for nowait
for (int i = 0; i < N; i++) {
#pragma omp cancel for
}
}
which is more 'optimal' but has the drawback to warn about having nowait and cancel mixed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With