当前位置:   article > 正文

(二) 任务调度_#pragma omp

#pragma omp

1、 schedule子句的用法

schedule(type,size) type表示调度类型,共有4种类型(static,dynamic,guided,runtime)可选,size参数定义了迭代次数最小的划分单位,每个线程依次分配size个迭代次数。

  1. #include<iostream>
  2. #include"omp.h"
  3. using namespace std;
  4. void main()
  5. {
  6. #pragma omp parallel for schedule(static,3)
  7. for(int i = 0; i < 9; i++)
  8. {
  9. printf("i=%d, thread_id=%d\n", i, omp_get_thread_num());
  10. }
  11. }

可以看出每个线程依次分配到3个连续的迭代计算

(1) dynamic动态调度

动态调度是动态的将迭代分配到各个线程上,可以使用size参数,不适合size参数情况下size值默认为1,根据每个线程的完成情况每次再分配2个迭代给已完成迭代任务的线程,使用size参数则每次分配size个迭代次数。较快迭代完成的线程可能执行更多次迭代,较慢的线程执行较少的迭代,以此来解决各线程间负载分配不平衡的问题。

  1. #include <iostream>
  2. #include "omp.h"
  3. using namespace std;
  4. void main() {
  5. #pragma omp parallel for schedule(dynamic, 2)
  6. for (int i = 0; i < 12; i++) {
  7. printf("i=%d, thread_id=%d\n", i * i * i * i, omp_get_thread_num());
  8. }
  9. }

执行乘法运算,i比较小的时候计算量小,所以可以看到编号为0的线程执行6次,编号为1、2和3的线程分别执行2次。

(2) guided调度

guided调度跟dynamic动态调度类似,是一种采用指导性的启发式自调度方法。刚开始时候每个线程会分配到较大的迭代块,之后每次分配到的迭代块会以指数级下降,直到下降到自定义的size大小,如果没有定义size,则默认为1.

2、sections制导指令

for制导指令用于迭代计算的任务分配,sections制导指令用于非迭代计算的任务分配,sections的语法格式如下: #pragma omp parallel sections[子句]

  1. #include <iostream>
  2. #include "omp.h"
  3. using namespace std;
  4. void main() {
  5. #pragma omp parallel sections
  6. {
  7. #pragma omp section
  8. {
  9. for (int i = 0; i < 4; i++)
  10. printf("i=%d, thread_id=%d\n", i, omp_get_thread_num());
  11. }
  12. #pragma omp section
  13. {
  14. for (int i = 0; i < 4; i++)
  15. printf("j=%d, thread_id=%d\n", i, omp_get_thread_num());
  16. }
  17. }
  18. }

sections语句块中共有2个section段落,所以生成2个线程并行执行。

3、single制导指令

在parallel制导指令产生的并行域中的语句,一般会默认生成4个不同的线程对相同的语句分别执行一次,如果想要其中某些操作只执行一次,可以使用single制导指令,其后的语句块只会被单个线程执行。

  1. #include <iostream>
  2. #include "omp.h"
  3. using namespace std;
  4. void main() {
  5. #pragma omp parallel
  6. {
  7. #pragma omp single
  8. { printf("single thread_id=%d\n", omp_get_thread_num()); }
  9. printf("多线程执行,thread_id=%d\n", omp_get_thread_num());
  10. }
  11. }

由single引导的语句块只执行一次,第二个printf语句没有single指令,所以被4个不同线程分别执行了一次。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号