OpenMP,更多线程导致减速的原因?(没有分享/没有rand()(我认为))

OpenMP, reason for slowdown with more threads? (no sharing/no rand() (I think..) )

本文关键字:分享 rand 没有 多线程 OpenMP      更新时间:2023-10-16

我在Intel®Xeon(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:6 s, 2:10 s, 3:15 s…12: 60年代。(在这里"工作"我指的是我指出的核心代码的确切部分,(不是整个omp循环),因为它花费了大部分时间,并确保我没有遗漏任何额外的东西)

核心代码中没有rand()操作。

动态或静态时间表在这里当然没有区别(我已经试过了)

似乎没有任何方式或形式的分享可能,因此我完全没有想法了…会是什么呢?我将非常感激如果你能帮助我这个(即使只是想法)!

注。这段代码的重点是使用myarray,用一个线程对其进行一些蒙特卡罗操作,然后收集微小的更改并对原始数组进行添加/减去。

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];
}

然而,你的代码看起来坏了(本质上不是线程安全的),看我的评论