OpenMP任务&数据环境

时间:2014-05-29 09:48:21

标签: c++ task openmp

我正在尝试为我的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始终会重新初始化为零。

我该如何解决?我正在使用任务,因为列表,但我的代码不起作用。

1 个答案:

答案 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()];
    }
}