OpenMP - make array counter with thread different start number

I am strugling with quite tricky (I guess) problem with parallel file reading.

Right now I have maped file using mmap and I want it to read values and put into three arrays. Well, maybe explanations isn't so clear, so this is my current code:

        int counter = header;

        #pragma omp parallel for shared (red,green,blue,map) private (i,j) firstprivate(counter)
        for(i = 0; i < x; i++)
        {
               for(j = 0; j < y; j++)
               {
                    red[i][j] = map[counter];
                    green[i][j] = map[counter+1];
                    blue[i][j] = map[counter+2];
                    counter+=3;
               }

        }

the header is beginning of a file - just image related info like size and some comments.

The problem here is, that counter has to be private. What I am finding difficult is to come up with dividing the counter across threads with different start numbers.

Can someone give me a hint how it can be achieved?

Answers


You could, if I've understood your code correctly, leave counter as a shared variable and enclose the update to it in a single section, something like

blue[i][j] = map[counter+2];
#pragma omp single 
{
  counter+=3;
}
}

I write something like because I haven't carefully checked the syntax nor considered the usefulness of some of the optional clauses for the single directive. I suspect that this might prove a real drag on performance.

An alternative would be to radically re-order your loop nest, perhaps (and again this is not carefully checked):

    #pragma omp parallel shared (red,green,blue,map) private (i,j) 
    #pragma for collapse(2) schedule(hmmm, this needs some thought)
    for(counter = 0; counter < counter_max; counter += 3)
    {
        for(i = 0; i < x; i++)
        {
               for(j = 0; j < y; j++)
               {
                    red[i][j] = map[counter];
               }

        }
    }
    ... loop for blue now ...
    ... loop for green now ...

Note that in this version OpenMP will collapse the first two loops into one iteration space, I expect this will provide better performance than uncollapsed looping but it's worth experimenting to figure that out. It's probably also worth experimenting with the schedule clause.


If I understood well your problem is that of initializing counter to different values for different threads.

If this is the case, then it can be solved like the linearization of matrix indexes:

size_t getLineStart(size_t ii, size_t start, size_t length) {
   return start + ii*length*3;
}

int counter;

#pragma omp parallel for shared (red,green,blue,map) private (i,j) private(counter)
for(size_t ii = 0; ii < x; ii++) {
  ////////
  // Get the starting point for the current iteration
  counter = getLineStart(ii,header,y);
  ////////
  for(size_t jj = 0; jj < y; jj++) {
    red  [i][j] = map[counter  ];
    green[i][j] = map[counter+1];
    blue [i][j] = map[counter+2];
    counter+=3;
   }
}   

These kind of counters are useful when it's hard to know how many values will be counted but then they don't work easily with OpenMP. But in your case it's trivial to figure out what the index is: 3*(y*i+j). I suggest fusing the loop and doing something like this:

#pragma omp parallel for
for(n=0; n<x*y; n++) {
    (&red  [0][0])[n] = map[3*n+header+0];
    (&green[0][0])[n] = map[3*n+header+1];
    (&blue [0][0])[n] = map[3*n+header+2];
}

Need Your Help

Bootstrap CSS isn't being overridden by Custom css

css twitter-bootstrap twitter-bootstrap-3 override

So I'm using bootstrap to make a navbar and used their example navbar as my foundation.

TweenLite - Animation Adding More Pixels Than Specified

jquery css animation greensock tweenlite

I am creating a vertical carousel that consists of 4 sections. I have an outer-wrapper set to the full height and width of the window and an inner-wrapper absolutely positioned inside this outer-wr...