部分和任务的OpenMP的区别 [英] Difference between section and task openmp

查看:298
本文介绍了部分和任务的OpenMP的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

之间有什么OpenMP中的区别:

What is the difference in OpenMP between :

#pragma omp parallel sections
    {
        #pragma omp section
        {
           fct1();
        }
        #pragma omp section
        {
           fct2();
        }
}

#pragma omp parallel 
{
    #pragma omp single
    {
       #pragma omp task
       fct1();
       #pragma omp task
       fct2();
    }
}

我不知道第二code是正确的...

I'm not sure that the second code is correct...

推荐答案

任务和部分之间的差异是在时帧,其中code将被执行。栏目有部分中封闭结构和(除非指定了 NOWAIT 条款)线程不会离开它,直到所有章节已执行:

The difference between tasks and sections is in the time frame in which the code will execute. Sections are enclosed within the sections construct and (unless the nowait clause was specified) threads will not leave it until all sections have been executed:

                 [    sections     ]
Thread 0: -------< section 1 >---->*------
Thread 1: -------< section 2      >*------
Thread 2: ------------------------>*------
...                                *
Thread N-1: ---------------------->*------

下面 N 线程遇到一个部分有两部分构造,比第一,第二花更多的时间。前两个线程执行的每一个部分。另 N-2 线程只需在隐式屏障等待的章节结束了构建(显示为 * )。

Here N threads encounter a sections construct with two sections, the second taking more time than the first. The first two threads execute one section each. The other N-2 threads simply wait at the implicit barrier at the end of the sections construct (show here as *).

任务排队和执行尽可能在所谓的任务调度点。在某些条件下,运行时可以允许线程之间移动的任务,甚至在其一生中的中间。这些任务被称为解开和解开任务可能会在某一调度点则可能是由运行到另一个线程迁移在一个线程中执行的,则

Tasks are queued and executed whenever possible at the so-called task scheduling points. Under some conditions, the runtime could be allowed to move task between threads, even in the mid of their lifetime. Such tasks are called untied and an untied task might start executing in one thread, then at some scheduling point it might be migrated by the runtime to another thread.

不过,任务和部分在许多方面相似。例如,下面的两个code片段实现基本相同的结果:

Still, tasks and sections are in many ways similar. For example, the following two code fragments achieve essentially the same result:

// sections
...
#pragma omp sections
{
   #pragma omp section
   foo();
   #pragma omp section
   bar();
}
...

// tasks
...
#pragma omp single nowait
{
   #pragma omp task
   foo();
   #pragma omp task
   bar();
}
#pragma omp taskwait
...

taskwait 作品非常喜欢屏障但任务 - 它可以确保当前执行流程将得到暂停,直到所有排队任务已经执行。它是一个调度点,即,它允许线程来处理任务。在需要一个构造,这样的任务将仅由一个线程创建。如果没有结构,每个任务都将获得创建 NUM_THREADS 倍,这可能不是自己想要的东西。在结构的 NOWAIT 子句指示其他线程没有等到构造被执行(即除去在构造末尾的隐式屏障)。因此,他们击中了 taskwait 立即开始处理任务。

taskwait works very like barrier but for tasks - it ensures that current execution flow will get paused until all queued tasks have been executed. It is a scheduling point, i.e. it allows threads to process tasks. The single construct is needed so that tasks will be created by one thread only. If there was no single construct, each task would get created num_threads times, which might not be what one wants. The nowait clause in the single construct instructs the other threads to not wait until the single construct was executed (i.e. removes the implicit barrier at the end of the single construct). So they hit the taskwait immediately and start processing tasks.

taskwait 是此处显示为清楚明确的调度点。也有隐含的调度点,里面最引人注目的屏障同步,无论明示或暗示的。因此,上述code也可以简单地写为:

taskwait is an explicit scheduling point shown here for clarity. There are also implicit scheduling points, most notably inside the barrier synchronisation, no matter if explicit or implicit. Therefore, the above code could also be written simply as:

// tasks
...
#pragma omp single
{
   #pragma omp task
   foo();
   #pragma omp task
   bar();
}
...

下面是可能发生的事情的一种可能的情况下,如果有三个主题:

Here is one possible scenario of what might happen if there are three threads:

               +--+-->[ task queue ]--+
               |  |                   |
               |  |       +-----------+
               |  |       |
Thread 0: --< single >-|  v  |-----
Thread 1: -------->|< foo() >|-----
Thread 2: -------->|< bar() >|-----

在这里显示在 | ... | 是调度点的动作(无论是 taskwait 指令或隐性障碍)。基本上线程 1 2 暂停他们在这一点上在做什么,并开始处理来自队列的任务​​。一旦所有的任务都已经被处理,线程恢复正常执行流程。需要注意的是线程 1 2 可能会达到线程之前调度点 0 已退出结构,所以离开 | 的需要没有必要保持一致(这是重新presented上图)上。

Show here within the | ... | is the action of the scheduling point (either the taskwait directive or the implicit barrier). Basically thread 1 and 2 suspend what they are doing at that point and start processing tasks from the queue. Once all tasks have been processed, threads resume their normal execution flow. Note that threads 1 and 2 might reach the scheduling point before thread 0 has exited the single construct, so the left |s need not necessary be aligned (this is represented on the diagram above).

这也可能会发生线程 1 能够处理完富()任务,并要求另一个甚至其他线程之前能够请求任务。因此,无论富()巴()可能由同一个线程得到执行:

It might also happen that thread 1 is able to finish processing the foo() task and request another one even before the other threads are able to request tasks. So both foo() and bar() might get executed by the same thread:

               +--+-->[ task queue ]--+
               |  |                   |
               |  |      +------------+
               |  |      |
Thread 0: --< single >-| v             |---
Thread 1: --------->|< foo() >< bar() >|---
Thread 2: --------------------->|      |---

另外,也可以,如果线程2来得太晚的挑出线程可能执行第二任务:

It is also possible that the singled out thread might execute the second task if thread 2 comes too late:

               +--+-->[ task queue ]--+
               |  |                   |
               |  |      +------------+
               |  |      |
Thread 0: --< single >-| v < bar() >|---
Thread 1: --------->|< foo() >      |---
Thread 2: ----------------->|       |---

在某些情况下,编译器或OpenMP运行时甚至可能会完全绕过任务队列和串行执行的任务:

In some cases the compiler or the OpenMP runtime might even bypass the task queue completely and execute the tasks serially:

Thread 0: --< single: foo(); bar() >*---
Thread 1: ------------------------->*---
Thread 2: ------------------------->*---

如果没有任务调度点是该地区的code里面present,只要它认为适当的OpenMP运行时可能会开始的任务。例如,它可能是所有任务推迟到在平行达到区域的最后屏障。

If no task scheduling points are present inside the region's code, the OpenMP runtime might start the tasks whenever it deems appropriate. For example it is possible that all tasks are deferred until the barrier at the end of the parallel region is reached.

这篇关于部分和任务的OpenMP的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆