Pregunta

So from what I understand, either of these are correct in ALL versions of openmp:

//int i declared in loop, explicitly private
#pragma omp parallel for
for (int i = 0; i < NUMEL; i++)
{
  foo(i);
}
//int i declared outsize loop, but is the iterated value, implicitly private
int i;
#pragma omp parallel for
for (i = 0; i < NUMEL; i++)
{
  foo(i);
}

However, I more commonly see the second than the first. Why is that?

¿Fue útil?

Solución

Because not everybody writes in C++ or targets a C99-compliant C compiler. Some prefer to stick with the old C requirement of having variables declared at the beginning of a block so that the code would be more compatible with older (pre-C99) C compilers.

Otros consejos

Declaring loop iterators outside of the loop is error prone and usually unnecessary. Perhaps the largest fractions of the questions on SO about OpenMP are problems due to inner loops and declaring iterators outside of loops.

int i,j;
#pragma omp parallel for
for(i=0; i<n; i++) {  //OpenMP makes the parallel index private by default
    for( j=0; j<n; j++) {  //error j should be private but is shared by default

If loop initial declarations were used this kind of error would not happen

#pragma omp parallel for
for(int i=0; i<n; i++) { //i is private
    for(int j=0; j<n; j++) {// j is private now

The C dialect GNU89 which GCC and ICC default to, unfortunately, does not allow loop initial declarations (even though it does allow mixed declarations) so a C99 (e.g GNU99) dialect or C++ is necessary for loop initial declarations.

However, sometimes it's useful to declare the iterator outside of the loop when the last iterator is desired. In that case lastprivate should be used. For example if I only wanted to loop over multiple of four elements and then know how many final elements there were to use I could do:

#include <stdio.h>
int main() {
    int i,j;
    int n,m;
    n = 10;
    m = 25;
    #pragma omp parallel for lastprivate(i,j)
    for(i=0; i<(n & -4); i++) {
        for(j=0; j<(m & -4); j++) {
        }
    }
    printf("%d %d\n",i, j);  //output 8, 24
}

A programmer once told me that he prefers the second version because you can see the value of i in the debugger after the loop has exited, which is useful for loops with complex conditions or breaks. But those loops won't parallelize well, so I would be surprised if that is the reason for OpenMP examples.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top