OpenMP,更多线程放缓的原因? (没有分享/没有兰德()(我认为..))

时间:2015-07-24 17:24:43

标签: c++ multithreading openmp

我正在运行我的代码在英特尔®至强(R)CPU X5680 @ 3.33GHz×12上。这是一个相当简单的OpenMP伪代码(OpenMP部分是精确的,只是为了紧凑和清晰而改变了其间的普通代码) :

vector<int> myarray(arraylength,something);

omp_set_num_threads(3);
#pragma omp parallel
{
    #pragma omp for schedule(dynamic)
    for(int j=0;j<pr.max_iteration_limit;j++)
    {
        vector<int> temp_array(updated_array(a,b,myarray));
        for(int i=0;i<arraylength;i++)
        {
            #pragma omp atomic
            myarray[i]+=temp_array[i];
        }
    }
}

复制temp_array函数采用的所有参数,以便不会发生冲突。 temp_array函数的基本结构:

vector<int> updated_array(myClass1 a, vector<myClass2> b, vector<int> myarray)
{
    //lots of preparations, but obviously there are only local variables, since 
    //function only takes copies

    //the core code taking most of the time, which I will be measuring:
    double time_s=time(NULL);
    while(waiting_time<t_wait) //as long as needed 
    {
        //a fairly short computaiton
        //generates variable: vector<int> another_array
        waiting_time++;
    }
    double time_f=time(NULL);

    cout<<"Thread "<<omp_get_thread_num()<<" / "<<omp_get_num_threads()
        << " runtime "<<time_f-time_s<<endl;

    //few more changes to the another_array

    return another_array;
}

问题和我尝试解决它:

添加更多线程(使用omp_set_num_threads(3);)确实会创建更多线程,但每个线程都会使作业更慢。例如。 1:6s,2:10s,3:15s ... 12:60s。 (在哪里“工作”我指的是我指出的核心代码的确切部分,(不是整个omp循环左右),因为它占用了大部分时间,并确保我没有遗漏任何其他内容)

核心代码中没有发生rand()事情。

动态或静态计划当然没有区别(我试过......)

似乎没有任何方式或形式的共享,因此我完全没有想法......它可以是什么?如果你能帮我解决这个问题,我将非常感激(即使只是想法)!

P.S。代码的要点是采用myarray,用单个线程对其进行一些montecarlo,然后收集微小的更改并添加/减去原始数组。

1 个答案:

答案 0 :(得分:0)

当您的代码在该互斥锁上遭受严重争用时,OpenMP可能会使用互斥锁实现原子访问。这将导致显着的性能损失。 如果updated_array()中的工作支配并行循环的成本,那么您最好将整个第二个循环放在一个关键部分中:

{   // body of parallel loop
    vector<int> temp_array = updated_array(a,b,myarray);
    #pragma omp critical(UpDateMyArray)
    for(int i=0;i<arraylength;i++)
        myarray[i]+=temp_array[i];
}

但是,您的代码看起来很糟糕(基本上不是线程安全的),请参阅我的评论。