这是正确的openMP用法吗? (或:我可以信任默认设置吗?)

时间:2012-02-14 10:47:51

标签: c++ openmp member

我目前第一次使用openMP,并且已经打击了“数据成员不能私有”的规则。

我想知道以下内容是否有效,或者最终是否有效:

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;
    }   
}

所以,我使用的是最小的语法,让openMP自己解决所有问题。此版本编译,输出正确(到目前为止)。 我之前尝试过的是

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;
    }   
}

然而,正如暗示的那样,无法编译,大概是因为tau和神经元是网络的数据成员。

那么问题是,如果我在第一版的运行中真的很幸运,我是否必须做类似的事情

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;
    }   
}

当然,我更喜欢坚持使用现在的版本,因为它太短且易于阅读,但我也想相信我的输出:) 我正在使用gcc 4.6.1

希望有人能够以正确的方式教育我。

2 个答案:

答案 0 :(得分:2)

在这个例子中,你最初做的事应该没问题:

  • 原因是您根本没有修改tau成员。因此,没有理由首先将其设为私有。如果未修改,则异步共享相同的值是安全的。
  • 至于neurons,您将独立修改元素。所以这里也没问题。

当您将变量声明为firstprivate时,它会将复制构造到所有线程中。所以shared(tempNeurons)肯定是你想做什么。

答案 1 :(得分:0)

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

  

第2.9.1节,数据共享属性规则

     
      
  • threadprivate指令中出现的变量是threadprivate。
  •   
  • 在构造内的范围内声明的具有自动存储持续时间的变量是私有的。
  •   
  • 具有动态存储持续时间的对象是共享的。
  •   
  • 共享静态数据成员。
  •   
  • for的一个for或parallel的关联for循环中的循环迭代变量是私有的。
  •   
  • 共享具有不具有可变成员的const限定类型的变量。
  •   
  • 在构造内的作用域中声明的具有静态存储持续时间的变量是共享的。
  •   
...
  
      
  • for或for for构造的关联for循环中的循环迭代变量可以列在private或lastprivate子句中。
  •   
  • 具有不具有可变成员的const限定类型的变量可以在firstprivate子句中列出。
  •   

但是,我仍然错过了构造外部自动变量的默认共享属性。