我目前第一次使用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
希望有人能够以正确的方式教育我。
答案 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子句中列出。
但是,我仍然错过了构造外部自动变量的默认共享属性。