我要求我的并行 OpenMP C 代码的执行时间解决方案

Posted

技术标签:

【中文标题】我要求我的并行 OpenMP C 代码的执行时间解决方案【英文标题】:Im asking for a solution for execution time to my parallel OpenMP C code 【发布时间】:2022-01-12 12:17:57 【问题描述】:
    pos = calloc(nbodies, sizeof(*pos));
    forces = calloc(nbodies, sizeof(*forces));
    //...more...
    printf("Calculating......\n");
    ene = 0.0;

    #pragma omp parallel shared(pos,forces,ene,i)
    
        #pragma omp for private(j,k,d,d2,d3,rij)
        for(i=0; i<nbodies; ++i)
            for(j=i+1; j<nbodies; ++j) 
                d2 = 0.0;
                for(k=0; k<3; ++k) 
                    rij[k] = pos[i][k] - pos[j][k];
                    d2 += rij[k]*rij[k];
                
                if (d2 <= cut2) 
                   d = sqrt(d2);
                   d3 = d*d2;
                   for(k=0; k<3; ++k) 
                        double f = -rij[k]/d3;
                        forces[i][k] += f;
                        #pragma omp atomic
                        forces[j][k] -= f;
                   
                   #pragma omp atomic
                   ene += -1.0/d; 
               
            
        
    

。 . . . . . . . 我为我的并行代码和 DevCpp 程序和 OpenMP 使用 2 个线程。 我的并行 OpenMP C 代码以与串行代码相同或慢得多的速度运行!有什么解决办法吗?

【问题讨论】:

您可以对 ene 变量和数组使用归约子句,您可以为每个线程使用一个数组来避免 pragma omp atomic 的同步成本。然后在平行区域之外将力减少到单个阵列中。 虚假共享可能也无济于事,因此最好处理forces 数组的本地副本,然后执行缩减以更快。 换句话说,你应该对eneforces 使用归约来代替原子。无需手动创建本地数组,因为这正是归约所要做的。 @Qubit 是的,完全类似于 github.com/dreamcrash/ScholarShipCode/blob/… 【参考方案1】:

引入同步总是有开销。但是你只需要这个,因为你试图保存几个操作。问问自己,当您有数十个内核以使工作并行时,节省 2 倍的工作量重要吗?

所以也许你应该让代码在标量方面更浪费一点,这意味着计算所有i,j的力量,但更容易并行化。

【讨论】:

以上是关于我要求我的并行 OpenMP C 代码的执行时间解决方案的主要内容,如果未能解决你的问题,请参考以下文章

C++ openMP 并行矩阵乘法

使用 OpenMP 并行化 C 中的基数排序

我可以将多个线程分配给 OpenMP 中的代码段吗?

c ++ OpenMP关键:“单向”锁定?

为啥 OpenMP 不并行化 vtk IntersectWithLine 代码

openmp/C++ 简单并行区域返回不一致的结果