【问题标题】:Difference between single and sections directive in OpenMPOpenMP 中的 single 和 section 指令之间的区别
【发布时间】:2014-06-26 16:28:45
【问题描述】:

据我了解, 我可以使用single 指令做与使用sections 相同的工作,只需添加nowait 标志

section 指令相比,以下代码对我来说没有什么不同:

    void main(){
    #pragma omp parallel
        {
            int tid = omp_get_thread_num();
    #pragma omp single nowait
            {
                printf("Thread %d in #1 single construct.\n", tid);
            }
    #pragma omp single nowait
            {
                printf("Thread %d in #2 single construct.\n", tid);
            }
    #pragma omp single nowait
            {
                printf("Thread %d in #3 single construct.\n", tid);
            }
        }
    }

谁能给我一些在不同场景中使用sectionssingle指令的例子?

【问题讨论】:

    标签: c++ multithreading parallel-processing openmp directive


    【解决方案1】:

    首先,singlesections 指令在读取代码时具有明显不同的语义目的,并且使用一个来模仿另一个可能会产生高度误导。

    关于技术细节,single 是唯一支持 copyprivate 子句的工作共享指令,它:

    ... 提供了一种使用私有变量的机制 从一个隐式任务的数据环境中广播一个值到 属于其他隐含任务的数据环境 平行区域。

    另一方面,sections 工作共享结构支持 lastprivatereduction 子句,而 single 不支持。

    最后,注意你的 sn-p:

    #pragma omp single nowait
            {
                printf("Thread %d in #1 single construct.\n", tid);
            }
    #pragma omp single nowait
            {
                printf("Thread %d in #2 single construct.\n", tid);
            }
    #pragma omp single nowait
            {
                printf("Thread %d in #3 single construct.\n", tid);
            } // No barrier here
    

    不模仿sections,而是模仿sections nowait。要模仿 sections,您必须记住让最后一个 single 构造保持其隐式屏障。

    【讨论】:

    • 如果我想做一个任务管理器功能,我应该选择哪个指令?
    • @CharlesChow 我不明白您所说的“任务管理器功能”是什么意思。如果你想使用任务级并行,OpenMP 3.X 和 4.0 支持task 指令。
    • 我的意思是一个注册新任务并将每个任务分配给线程的程序。你提到我应该为单个指令留下一个障碍,是不是意味着我只是在single的最后一部分删除了nowait
    • 我认为阅读此answer 可能对您有所帮助,了解部分和任务之间的差异。
    【解决方案2】:

    在某些情况下,single nowait 构造的行为方式可能与 sections 构造相同。然而,OpenMP 规范只要求只有一个线程执行single 构造。它不需要空闲线程承担其他后续构造。对于所有 OpenMP 实现,您不能简单地依赖此行为。大多数人都会按照您的预期行事,但无法保证。

    另一件值得一提的是,大多数实现都使用票务系统将single 区域分配给线程。 sections 的常用代码转换是映射到for 工作共享结构,方法是将sections 结构转换为for 循环并为section 结构使用switch 语句。所以,还有更多关于执行的保证。

    干杯, -迈克尔

    【讨论】:

    • 我说得对吗,即使在sections 中,规范也不是require that idle threads take on the other subsequent constructs? (请参阅here 以更广泛地解释我的意思,即时间表是实施定义的)
    • 你是对的。如果存在线程的部分较少,则某些部分可能会保持空闲状态。使用上面的单一模式,虽然有多个区域可以并行运行,但从技术上讲只能执行一个线程。
    猜你喜欢
    • 2015-05-18
    • 1970-01-01
    • 2021-07-06
    • 2015-01-12
    • 2011-10-04
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多