2

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?

pippin1289
  • 4,861
  • 2
  • 22
  • 37
IdeaHat
  • 7,641
  • 1
  • 22
  • 53
  • I have wondered the same thing. I think most people don't know any better. It also often leads to errors because people assume that inner loops will work fine as well but they don't (without explicitly declaring the inner iterator private). The GNU89 dialect (used by ICC also) allows mixed declarations so I don't really understand why people still like to declare iterators outside the loop. It's error prone. – Z boson Apr 01 '14 at 19:23
  • It turns out that although GNU89 does allow mixed declarations it still does not allow loop initial declarations so a C99 (e.g. GNU99) or C++ dialect is necessary. I updated my answer to fix this. – Z boson Apr 23 '14 at 07:13

3 Answers3

4

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.

Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
  • But any C++ compiler shouldn't care? I mean, it is probably likely openmp is more used for C than C++, but it still seems odd that 99% of all examples are in the C style... – IdeaHat Apr 01 '14 at 15:34
  • Most examples are probably targeted at both C and C++ users. Also OpenMP lags way behind the development of C++, e.g. `for` constructs with random-access iterators became part of the standard as late as in version 3.0 (2008). – Hristo Iliev Apr 01 '14 at 15:48
  • Another reason is to have the iterator variable used in multiple `for` loops within the same function. – Thomas Matthews Apr 01 '14 at 17:34
  • Another reason is to have the iterator variable available after the `for` loop. – Thomas Matthews Apr 01 '14 at 17:35
  • 1
    @ThomasMatthews, that does not work so well with OpenMP since iterators are private. Lastprivate can help sometimes but in practice I almost never see it used. – Z boson Apr 01 '14 at 19:20
2

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
}
Community
  • 1
  • 1
Z boson
  • 32,619
  • 11
  • 123
  • 226
0

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.

japreiss
  • 11,111
  • 2
  • 40
  • 77