部分和任务OpenMP之间的区别

发布于 2025-02-11 00:33:47 字数 383 浏览 3 评论 0原文

OpenMP的区别是什么:

#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();
    }
}

我不确定第二个代码是否正确...

What is the difference in OpenMP between :

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

and :

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

缱绻入梦 2025-02-18 00:33:47

任务和部分之间的区别在于代码执行的时间范围。部分包含在章节构造中,并且(除非指定了Nowait子句)线程将在执行所有章节之前不会离开它:

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

此处n线程遇到一个部分带有两个部分的构造,第二部分花费的时间比第一个花费更多。前两个线程每个执行一个部分。另一个n-2线程只需在各节构造末尾的隐式障碍物上等待(在此处显示为*)。

在可能的任务调度点上尽可能将任务排队和执行。在某些情况下,即使在一生的中期,也可以允许运行时在线程之间移动任务。此类任务称为UNIDINE,并且可能会在一个线程中开始执行一个未接触的任务,然后在某些调度点可以将其迁移到另一个线程。

尽管如此,任务和部分在许多方面都相似。例如,以下两个代码片段实现了基本相同的结果:

// 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
...

task Wait非常像障碍,但对于任务 - 它可确保当前的执行流将被暂停,直到所有排队的任务都排队已执行。这是一个调度点,即允许线程处理任务。需要单个构造,以便仅一个线程创建任务。如果没有单个构造,则每个任务都将被创建num_threads次,这可能不是一个人想要的。 NowAit 单一 construct中的子句指示其他线程不要等到执行单个 construct执行(即在末尾删除了隐式障碍物构造的)。因此,他们立即击中taskwait并开始处理任务。

taskwait是此处显示的明确调度点。也有隐式调度点,最著名的是在屏障同步内部,无论是明确还是隐式。因此,上述代码也可以简单地写成:

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

以下是有三个线程可能发生的情况:

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

|中显示的情况。 ... |是调度点的操作(task Wait指令或隐式障碍)。基本上是线程12暂停了他们在那时的工作,并从队列开始处理任务。处理所有任务后,线程将恢复其正常执行流。请注意,线程12可能会在线程0之前到达调度点左| s不需要对齐(上图上表示)。

可能会碰到线程1能够完成处理foo()任务,甚至在其他线程能够请求任务之前请求另一个。因此,这两个foo()bar()可能会由同一线程执行:

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

如果TREED 2也出现,则可能会执行单调的线程可能执行第二个任务迟到:

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

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

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

如果该区域代码中没有任务调度点,则OpenMP运行时可能会在认为合适的情况下启动任务。例如,可能会推迟所有任务,直到达到并行区域结束时的屏障为止。

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: ---------------------->*------

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.

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 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 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() >|-----

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).

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: --------------------->|      |---

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: ----------------->|       |---

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: ------------------------->*---

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.

独行侠 2025-02-18 00:33:47

我不是OpenMP的专家,但试图使用taske节

pection 任务 poction

int fib(int n)
{
    int i, j;
    if (n < 2)
        return n;
    else
    {
#pragma omp parallel sections       
{
#pragma omp section             
{
                i = fib(n - 1);
            }
#pragma omp section             
{
                j = fib(n - 2);
            }
        }
        printf("Current int %d is on thread %d \n", i + j, omp_get_thread_num());
        return i + j;
    }
}

int main()
{
    int n = 10;

#pragma omp parallel shared(n)  {
#pragma omp single      {
            printf("%d\n", omp_get_num_threads());
            printf("fib(%d) = %d\n", n, fib(n));
        }
    }
}

poction task

#include <stdio.h>
#include <omp.h>
int fib(int n)
{
  int i, j;
  if (n<2)
    return n;
  else
    {
       #pragma omp task shared(i) firstprivate(n)
       i=fib(n-1);

       #pragma omp task shared(j) firstprivate(n)
       j=fib(n-2);

       #pragma omp taskwait
    printf("Current int %d is on thread %d \n", i + j, omp_get_thread_num());
       return i+j;
    }
}

int main()
{
  int n = 10;

  #pragma omp parallel shared(n)
  {
    #pragma omp single
    {
    printf("%d\n", omp_get_num_threads());
        printf ("fib(%d) = %d\n", n, fib(n));
    }
  }
}

章节的结果:

12
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 13 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 21 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 13 is on thread 0
Current int 34 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 13 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 21 is on thread 0
Current int 55 is on thread 4
fib(10) = 55

任务结果:

12
Current int 1 is on thread 3
Current int 2 is on thread 3
Current int 1 is on thread 8
Current int 2 is on thread 8
Current int 1 is on thread 8
Current int 1 is on thread 4
Current int 1 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 3 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 1 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 3 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 1 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 3 is on thread 11
Current int 5 is on thread 11
Current int 8 is on thread 11
Current int 1 is on thread 8
Current int 2 is on thread 8
Current int 3 is on thread 8
Current int 5 is on thread 8
Current int 13 is on thread 8
Current int 1 is on thread 7
Current int 2 is on thread 7
Current int 1 is on thread 7
Current int 1 is on thread 7
Current int 1 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 1
Current int 1 is on thread 6
Current int 2 is on thread 6
Current int 1 is on thread 9
Current int 2 is on thread 9
Current int 1 is on thread 2
Current int 2 is on thread 7
Current int 3 is on thread 7
Current int 5 is on thread 7
Current int 2 is on thread 5
Current int 5 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 1 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 3 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 1 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 3 is on thread 5
Current int 5 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 1 is on thread 8
Current int 2 is on thread 8
Current int 5 is on thread 8
Current int 3 is on thread 1
Current int 8 is on thread 1
Current int 21 is on thread 1
Current int 1 is on thread 10
Current int 3 is on thread 10
Current int 8 is on thread 0
Current int 1 is on thread 4
Current int 3 is on thread 4
Current int 1 is on thread 9
Current int 3 is on thread 9
Current int 8 is on thread 9
Current int 3 is on thread 2
Current int 5 is on thread 3
Current int 13 is on thread 3
Current int 5 is on thread 6
Current int 13 is on thread 7
Current int 8 is on thread 10
Current int 21 is on thread 10
Current int 34 is on thread 3
Current int 55 is on thread 1
fib(10) = 55

在分发计算资源时,任务似乎比部分明智得多

-------------------------------------------------------------------- -Edit ----------------------------------

对于为此问题寻找答案的人,请参阅本文下的评论。

I am not an expert in OpenMP but tried to test fib sequence on my machine using both task and sections

sections

int fib(int n)
{
    int i, j;
    if (n < 2)
        return n;
    else
    {
#pragma omp parallel sections       
{
#pragma omp section             
{
                i = fib(n - 1);
            }
#pragma omp section             
{
                j = fib(n - 2);
            }
        }
        printf("Current int %d is on thread %d \n", i + j, omp_get_thread_num());
        return i + j;
    }
}

int main()
{
    int n = 10;

#pragma omp parallel shared(n)  {
#pragma omp single      {
            printf("%d\n", omp_get_num_threads());
            printf("fib(%d) = %d\n", n, fib(n));
        }
    }
}

task

#include <stdio.h>
#include <omp.h>
int fib(int n)
{
  int i, j;
  if (n<2)
    return n;
  else
    {
       #pragma omp task shared(i) firstprivate(n)
       i=fib(n-1);

       #pragma omp task shared(j) firstprivate(n)
       j=fib(n-2);

       #pragma omp taskwait
    printf("Current int %d is on thread %d \n", i + j, omp_get_thread_num());
       return i+j;
    }
}

int main()
{
  int n = 10;

  #pragma omp parallel shared(n)
  {
    #pragma omp single
    {
    printf("%d\n", omp_get_num_threads());
        printf ("fib(%d) = %d\n", n, fib(n));
    }
  }
}

Result for sections:

12
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 13 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 21 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 13 is on thread 0
Current int 34 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 13 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 5 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 1 is on thread 0
Current int 3 is on thread 0
Current int 8 is on thread 0
Current int 21 is on thread 0
Current int 55 is on thread 4
fib(10) = 55

Result for task:

12
Current int 1 is on thread 3
Current int 2 is on thread 3
Current int 1 is on thread 8
Current int 2 is on thread 8
Current int 1 is on thread 8
Current int 1 is on thread 4
Current int 1 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 3 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 1 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 3 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 1 is on thread 11
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 3 is on thread 11
Current int 5 is on thread 11
Current int 8 is on thread 11
Current int 1 is on thread 8
Current int 2 is on thread 8
Current int 3 is on thread 8
Current int 5 is on thread 8
Current int 13 is on thread 8
Current int 1 is on thread 7
Current int 2 is on thread 7
Current int 1 is on thread 7
Current int 1 is on thread 7
Current int 1 is on thread 0
Current int 1 is on thread 0
Current int 2 is on thread 0
Current int 3 is on thread 0
Current int 1 is on thread 1
Current int 1 is on thread 6
Current int 2 is on thread 6
Current int 1 is on thread 9
Current int 2 is on thread 9
Current int 1 is on thread 2
Current int 2 is on thread 7
Current int 3 is on thread 7
Current int 5 is on thread 7
Current int 2 is on thread 5
Current int 5 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 1 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 3 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 1 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 3 is on thread 5
Current int 5 is on thread 5
Current int 1 is on thread 5
Current int 2 is on thread 5
Current int 1 is on thread 11
Current int 2 is on thread 11
Current int 1 is on thread 8
Current int 2 is on thread 8
Current int 5 is on thread 8
Current int 3 is on thread 1
Current int 8 is on thread 1
Current int 21 is on thread 1
Current int 1 is on thread 10
Current int 3 is on thread 10
Current int 8 is on thread 0
Current int 1 is on thread 4
Current int 3 is on thread 4
Current int 1 is on thread 9
Current int 3 is on thread 9
Current int 8 is on thread 9
Current int 3 is on thread 2
Current int 5 is on thread 3
Current int 13 is on thread 3
Current int 5 is on thread 6
Current int 13 is on thread 7
Current int 8 is on thread 10
Current int 21 is on thread 10
Current int 34 is on thread 3
Current int 55 is on thread 1
fib(10) = 55

It seems that task is much wiser than sections while distributing computing resources

-----------------------------EDIT-----------------------------

For people who looking for answers for this question, please see the comment under this post.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文