首页 > 解决方案 > 为什么 OpenMP 比顺序执行慢?

问题描述

我有以下代码:

    omp_set_num_threads(10);
    
    int N = 10000;
    int chunk = 1000;
    int i;
    float a[N];

    for (i=0; i < N; i++) 
    {
            a[i] = i;
    }

    #pragma omp parallel private(i)
    {
            #pragma omp for schedule(dynamic,chunk) nowait
            for (i=0; i < N; i++) a[i] = a[i] + a[i];
    } 

顺序代码是相同的,没有两个 pragma 指令。

顺序~150us 并行~1100us

这是一个巨大的差距,我预计它会反过来。

是否有人知道出了什么问题,或者 OpenMP 在后台有很多事情要做?有人有一个例子,我可以看到并行化的 for 循环更快吗?

谢谢

标签: c++parallel-processingopenmp

解决方案


启动十个线程并管理它们比添加 10,000 个元素更昂贵。如果您在一个真正核心少于 10 个的系统上,它们将竞争时间片,并导致上下文切换和(可能)更多的缓存未命中。而且您选择了动态调度,这意味着需要进行一些同步来帮助线程确定它们将要执行哪些块(不是很多,但在分配的工作相比之下相当微不足道时足以减慢速度) .

在一个轶事中,启动一个无操作线程并立即将其分离大约需要 10 μs,而这些线程不需要做任何事情。在您的情况下,这只是启动线程的 100 μs,忽略线程可能引入的所有其他低效率。

并行化有助于大型工作负载,或者当工作人员多次用于许多中等规模的任务时(因此启动线程的成本只是他们所做工作的一小部分)。但是执行 10,000 次加法对 CPU 来说是小菜一碟。您只是做得还不够,无法从并行化中受益。


推荐阅读