Reputation: 395
I have the following piece of code which I want to add omp for to:
for ( int i = 0 ; i < N ; i++ ) {
double max2 = 0.;
(calculate max2);
for ( int j = 0 ; j < 3 ; j++) {
int m = group[i].member[j];
if ( members[m].norm < max2 ) {
members[m].norm = max2;
}
}
}
The access to members needs to be protected but I would like to use a named critical section so as to avoid the speed penalty of effectively serializing that loop. What I want to do is this:
#pragma omp parallel for
for ( int i = 0 ; i < N ; i++ ) {
double max2 = 0.;
(calculate max2);
for ( int j = 0 ; j < 3 ; j++) {
int m = group[i].member[j];
#pragma omp critical (m)
if ( members[m].norm < max2 ) {
members[m].norm = max2;
}
}
}
so that only threads actually writing to the same m value wait for each other. My question is: is "m" used as a string for the critical name or is it actually evaluated and its value used as the name of the critical section? It does compile but I do not know if it does what I think it does. I would greatly appreciate if anyone can clarify what omp does here (eg how omp implements these).
Thank you * very much.
Upvotes: 3
Views: 2396
Reputation: 2863
The name of a critical
must be a compile-time constant. But it's not a string or something, it's just a name that you put in parenthesis, e.g.
#pragma omp critical (foo)
For your pattern you will have to use locks, similar to this:
#pragma omp parallel for
for ( int i = 0 ; i < N ; i++ ) {
double max2 = 0.;
(calculate max2);
for ( int j = 0 ; j < 3 ; j++) {
omp_lock_t * lck = group[i].member[j].my_lock;
omp_set_lock(*lck);
if ( members[m].norm < max2 ) {
members[m].norm = max2;
}
omp_unset_lock(*lck);
}
}
Please note, locks in OpenMP have to be initialized. Please see https://www.openmp.org/spec-html/5.0/openmpse31.html#x191-9120003.3 for more information.
Upvotes: 2