我正在尝试为我的C ++ / OpenMP程序使用任务构造:
#pragma omp parallel
{
typename ClusterNormal<DIM>::VectorMean ResultMeanThread;
ResultMeanThread.setZero();
#pragma omp single
for(list<unsigned int>::const_iterator it=IDLeft.cbegin(); it!=IDLeft.cend(); it++)
{
#pragma omp task
{
ResultMeanThread += Data[*it];
}
}
}
此代码计算IDLeft中指示的数据元素的某些VectorMean
(它不介意它们是什么,但它们有运算符+已定义)的总和。
每个线程都使用全零来初始化VectorMean
。我的问题是在for循环之后,ResultMeanThread
仍然是由全零组成的。
执行任务时,会正确计算总和,但在执行任务后,ResultMeanThread
始终会重新初始化为零。
我该如何解决?我正在使用任务,因为列表,但我的代码不起作用。
答案 0 :(得分:1)
我发现问题是ResultMeanThread
声明私有变量。
我尝试了这段代码,声明了ResultMeanThread
的向量,就像共享变量一样(向量的长度是线程的数量),所以每个线程只能访问向量的一个元素(没有竞争条件)。
在前面的代码中,由于ResultMeanThread
构造,每个task
都为零。每次执行task
时,私有变量都会设置为其初始值。由于task
list
构造
以下是代码:
vector<typename ClusterNormal<DIM>::VectorMean> ResultMeanThread;
typename ClusterNormal<DIM>::VectorMean ResultMeanFinal;
//here i set initial values to zero, and number of vector elements equal to total number of threads
#pragma omp parallel
{
#pragma omp single
for(list<unsigned int>::const_iterator it=IDLeft.cbegin(); it!=IDLeft.cend(); it++)
{
#pragma omp task
{
ResultMeanThread[omp_get_thread_num()] += Data[*it];
}
}
#pragma omp taskwait
// Final sum
#pragma omp critical
{
ResultMeanFinal+=ResultMeanThread[omp_get_thread_num()];
}
}