2

I tried to parallel function, that allocates memory, but I had an exception of bad heap. Memory must have used some threads in one time.

void GetDoubleParameters( CInd *ci )
{
    for(int i=0;i<ci->size();i++)
    {
        void *tmp;
        #pragma omp parallel private (tmp)
        {
            for(int j=0;j<ci[i].getValues().size();j++)
            {
                tmp = (void*)new double(ci[i].getValues()[j]);
                ci->getParameters().push_back(tmp);
            }
        }

    }
}
Pavel
  • 71
  • 8
  • Are you sure that you do not exhaust memory for good ? By the way, there is only one thread, so that the allocation operations will not really run in parallelel. You also push everything in the same vector... – Christophe Jan 02 '16 at 14:31
  • @Christophe I'd like tmp be pushed into vector in some threads. Is it real? – Pavel Jan 02 '16 at 14:39
  • Yes, but if you have 100 threads, while one will allocate, the 99 others will have to wait. SO in theroy it's parrallel, but in practice, it will be almost sequential. – Christophe Jan 02 '16 at 15:03
  • @Christophe, Can I win time, using OpenMP in functions like that? – Pavel Jan 02 '16 at 15:24
  • 1
    Note that each iteration of the external `for` is executed by multiple thread, each doing the same work. Is that by design? Also, all those threads call `push_back` in parallel. Is the parameters type thread safe? If not, you're probably corrupting it. Lastly, there's no point in declaring `tmp` outside the parallel section - just move it in, and omit the `private` clause (that's not the cause of the error, but it's useless). – Eran Jan 02 '16 at 16:02
  • 1
    @Christophe, the allocation can be done in parallel (depending on implementation), and could be much faster than the rest of the work (again, not guaranteed). So it's quite possible the allocation will not significantly hurt parallelism. OTOH, using vector's `push_back` (if that's really the container) will not be thread safe, and if it is, it will probably have a much bigger affect on parallelism. But that's somewhat a guess - Павел Воевода, care to provide an example without using types we can't see? – Eran Jan 02 '16 at 16:15
  • 1
    I think you want `#pragma omp for` on the loop over `j`. That would fix one problem then you have to deal with `push_back`. See [here](https://stackoverflow.com/questions/18669296/c-openmp-parallel-for-loop-alternatives-to-stdvector/18671256#18671256). – Z boson Jan 02 '16 at 19:25

1 Answers1

0

The problem is the line:

ci->getParameters().push_back(tmp);

ci is accessed by all parallel threads at once, and its parameters element with the push_back routine (probably a std::vector) is probably not thread-safe. You will have to organize some guards around this code. Something like:

omp_lock_t my_lock;
...
// initialize lock
omp_init_lock (&my_lock);
...

// do something sensible in parallel
  ...
  {
      omp_guard my_guard (my_lock);
      // protected region starts here
      // only one thread at a time works here
  }
  // more parallel work
  ...
}
omp_destroy_lock (&my_lock);
Trantor
  • 768
  • 1
  • 8
  • 27