简体   繁体   中英

is this proper openMP usage? (or: can I trust the default settings?)

I am presently using openMP for the first time, and have hit my head against the "data members cannot be private"-rule.

I would like to know whether the below is valid, or if it will eventually break:

class network
{
    double tau;
    void SomeFunction();
};

void network::SomeFunction()
{
    #pragma omp parallel for // <-the openMP call
    for (uint iNeu=0;iNeu<nNeurons;++iNeu)
    {
        neurons[iNeu].timeSinceSpike+=tau;  //tau is defined in some other place
        neurons[iNeu].E+=tau*tau;
    }   
}

So, I am using the minimal syntax, and letting openMP figure out everything on its own. This version compiles, and the output is correct (so far). What I tried before that was

void network::SomeFunction()
{
    #pragma omp parallel for default(none) shared(neurons) firstprivate(tau)  // <-the openMP call
    for (uint iNeu=0;iNeu<nNeurons;++iNeu)
    {
        neurons[iNeu].timeSinceSpike+=tau; //tau is defined in some other place
        neurons[iNeu].E+=tau*tau;
    }   
}

However, as hinted, that won't compile, presumably because tau and neurons are data members of network.

The question then is, if I have really just been lucky in my runs of the first version, and whether I have to do something like

void network::SomeFunction()
{
    double tempTau=tau;
    vector <neuron> tempNeurons=neurons; //in realtity this copy-process would be quite involved
    #pragma omp parallel for shared(tempNeurons) firstprivate(tempTau)// <-the openMP call
    for (uint iNeu=0;iNeu<nNeurons;++iNeu)
    {
        tempNeurons[iNeu].timeSinceSpike+=tempTau;
        tempNeurons[iNeu].E+=tempTau*tempTau;
    }   
}

Naturally, I would much prefer to stick with the present version, as it is so short and easy to read, but I would also like to trust my output :) I am using gcc 4.6.1

Hope someone can educate me on the proper way to do it.

In this example, what you are initially doing should be fine:

  • The reason is that you aren't modifying the tau member at all. So there's no reason to make it private in the first place. It's safe to asynchronously share the same value if it isn't modified.
  • As for neurons , you are modifying the elements independently. So there's no problem here either.

When you declare a variable as firstprivate , it gets copy constructed into all the threads. So shared(tempNeurons) is definitely not what you want to do.

http://www.openmp.org/mp-documents/OpenMP3.1.pdf

Section 2.9.1, Data-sharing Attribute Rules

  • Variables appearing in threadprivate directives are threadprivate.
  • Variables with automatic storage duration that are declared in a scope inside the construct are private.
  • Objects with dynamic storage duration are shared.
  • Static data members are shared.
  • The loop iteration variable(s) in the associated for-loop(s) of a for or parallel for construct is (are) private.
  • Variables with const-qualified type having no mutable member are shared.
  • Variables with static storage duration that are declared in a scope inside the construct are shared.
...
  • The loop iteration variable(s) in the associated for-loop(s) of a for or parallel for construct may be listed in a private or lastprivate clause.
  • Variables with const-qualified type having no mutable member may be listed in a firstprivate clause.

However, I yet miss the default sharing attribute for automatic variables outside a construct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM