我试图并行我的代码与openmp。
我有一个全局向量,所以我可以用函数来扩展它。有没有一种方法,我可以分配一个拷贝的矢量,每个线程,所以他们可以做的东西?下面是一些描述我的问题的伪代码:
double var = 1;
std::vector<double> vec;
void function()
{
vec.push_back(var);
return;
}
int main()
{
omp_set_num_threads(2);
#pragma omp parallel
{
#pragma omp for private(vec)
for (int i = 0; i < 4; i++)
{
function();
}
}
return 0;
}
指出:
- 我希望每个线程都有一个自己的向量,以安全的特定值,以后只有相同的线程需要过剩
- 每个线程调用一个函数(有时是相同的),然后在向量上做一些工作(改变特定的值)
- (在我的原始代码有许多向量和函数,我只是试图打破问题)
我试过#pragma omp threadprivate(),但这只适用于变量,而不是向量。另外,在并行区域内重新声明向量也没有帮助,因为我的函数总是与全局向量一起工作,当不同的线程同时调用它时,这会导致问题。
是否有一种方法可以将向量的副本分配给每个线程这样他们就可以用它做什么了?
是的,firstprivate子句这样做:
因此,它为每个线程创建了变量的私有副本,但是这个私有变量的范围是OpenMP构造之后的结构化块。. 在这个块之外,你可以访问全局变量:第一个private子句声明一个或多个列表项为private的值初始化每个任务当遇到构造时,对应的原始项。
#pragma omp ... firstprivate(vec)
{
vec.push_back(...); // private copy is changed here, which is threadsafe
}
void function()
{
vec.push_back(var); // the global variable is changed here, which is not threadsafe
return;
}
如果您希望在函数中使用变量的私有副本,则必须将其作为引用传递给函数:
void function(std::vector<double>& x, double y)
{
x.push_back(y);
return;
}
...
#pragma omp for firstprivate(vec)
for (int i = 0; i < 4; i++)
{
function(vec, 1);
}
请注意,正如@JeromeRichard指出和解释的那样,你不应该在代码中使用全局变量。