为什么不打开mp并行化这段代码?

Aak*_*nuj 2 c openmp

此代码不会使代码更快地计算4个和.相反,它甚至需要更多时间.此外输出不是预期的.

#include <stdio.h>
#include <omp.h>
int main()
{
    int i,j,k,l;
    int sum = 0,sum1 = 0,sum2 = 0,sum3 = 0;
    #pragma omp parallel
    {
        #pragma omp sections
        {
            #pragma omp section
            {
                printf("%d",omp_get_thread_num());
                for(i = 0; i < 500000000; i++) sum = sum + 1;
            }
            #pragma omp section
            {
                printf("%d",omp_get_thread_num());
                for(i = 0; i < 500000000; i++) sum1 = sum1 + 1;
            }
            #pragma omp section
            {
                printf("%d",omp_get_thread_num());
                for(i = 0; i < 500000000; i++) sum2 = sum2 + 1;
            }
            #pragma omp section
            {
                printf("%d",omp_get_thread_num());
                for(i = 0; i < 500000000; i++) sum3 = sum3 + 1;
            }
        }
    }
    printf("sum is %d %d %d %d",    sum,sum1,sum2,sum3);
}
Run Code Online (Sandbox Code Playgroud)

输出是 sum is 218748707 222052401 239009041 196849489

请告诉我在这里使用openmp的缺陷.

Hri*_*iev 5

减速来源于这样的事实即sum,sum1,sum2sum3被共享的变量,因此,编译器必须产生取/更新/存储指令对每个增量,而不是仅仅保持在寄存器中的中间和作为为串行版本的情况.

你应该将每个和使用它所使用的线程本地.最简单的方法是减少每个总和:

#pragma omp parallel private(i) reduction(+:sum,sum1,sum2,sum3)
{
    // Rest of the code goes unchanged
}
Run Code Online (Sandbox Code Playgroud)

private(i)将解决问题的结果不正确.reduction(+:sum,sum1,sum2,sum3)将使每个线程累积自己的sum,和的副本sum1,sum2sum3最终将本地副本添加起来以形成最终值.

以下是一些表现数据:

串行版 - 3.812秒:

$ gcc -o mp.x mp.c -lgomp
$ time ./mp.x
0000sum is 500000000 500000000 500000000 500000000
./mp.x  3.81s user 0.00s system 99% cpu 3.812 total
Run Code Online (Sandbox Code Playgroud)

具有共享变量的OpenMP版本 - 7.982秒:

$ gcc -fopenmp -o mp.x mp.c
$ time OMP_NUM_THREADS=4 ./mp.x
0132sum is 500000000 500000000 500000000 500000000
OMP_NUM_THREADS=4 ./mp.x  21.88s user 0.86s system 284% cpu 7.982 total
Run Code Online (Sandbox Code Playgroud)

OpenMP版本减少 - 1.226秒:

$ gcc -fopenmp -o mp.x mp.c
$ time OMP_NUM_THREADS=4 ./mp.x
0321sum is 500000000 500000000 500000000 500000000
OMP_NUM_THREADS=4 ./mp.x  4.53s user 0.00s system 370% cpu 1.226 total
Run Code Online (Sandbox Code Playgroud)

还存在另外会减慢速度另一个代码转换,这是一个事实,即sum,sum1,sum2sum3位于主程序的堆叠上,而部分代码正在由OpenMP的处理器中提取并投入单独的函数,然后由称为并行团队中的每个线程.该函数提供了一个数据结构,其中包含指向四个共享和的指针,并且代码与这些指针一起操作.您可以在两种情况下比较汇编器输出并亲自查看 - 如果您想深入了解并行性能,那么这样做非常有益.