OpenMP中任务调度主要针对并行的for循环,当循环中每次迭代的计算量不相等时,如果简单地给各个线程分配相同次数的迭代,则可能会造成各个线程计算负载的不平衡,影响程序的整体性能。

如下面的代码中,如果每个线程执行的任务数量平均分配,有的线程会结束早,有的线程结束晚:

 #include<stdio.h>
#include<omp.h> int main(){
int a[][] = {};
#pragma omp parallel for
for (int i =; i < ; i++){
for(int j = i; j < ; j++ )
a[i][j] = ((i%)*(j%)%);
}
return ;
}

为此,OpenMP提供了schedule子句来实现任务的调度。

schedule子句:

  schedule(type[, size]),

  参数type是指调度的类型,可以取值为static,dynamic,guided,runtime四种值。其中runtime允许在运行时确定调度类型,因此实际调度策略只有前面三种。

  参数size表示每次调度的迭代数量,必须是整数。该参数是可选的。当type的值是runtime时,不能够使用该参数。

1.静态调度static

  大部分编译器在没有使用schedule子句的时候,默认是static调度。static在编译的时候就已经确定了,那些循环由哪些线程执行。

  当不使用size 时,将给每个线程分配┌N/t┐个迭代。当使用size时,将每次给线程分配size次迭代。

  如下面代码:

 #include<stdio.h>
#include<omp.h>
int main(){
int a[][] = {};
#pragma omp parallel for schedule(static)
//#pragma omp parallel for schedule(static,5)
for (int i =; i < ; i++){
printf("id=%d i=%d\n",omp_get_thread_num(),i);
}
return ;
}

  在四核机器上执行:

  (1)当不使用参数时,100/4=25,0-24由1号线程执行;25-49由2号线程执行;50-74由3号线程执行;75-99由4号线程执行

  (1)当不使用参数时,x(x=0,1,2,3)线程执行((n/5)%4)任务。其中n=0-99。

2.动态调度dynamic

  动态调度依赖于运行时的状态动态确定线程所执行的迭代,也就是线程执行完已经分配的任务后,会去领取还有的任务。由于线程启动和执行完的时间不确定,所以迭代被分配到哪个线程是无法事先知道的。

  当不使用size 时,是将迭代逐个地分配到各个线程。当使用size 时,逐个分配size个迭代给各个线程。

  如下面代码:

 #include<stdio.h>
#include<omp.h>
int main(){
int a[][] = {};
#pragma omp parallel for schedule(dynamic)
//#pragma omp parallel for schedule(dynamic,5)
for (int i =; i < ; i++){
printf("id=%d i=%d\n",omp_get_thread_num(),i);
}
return ;
}

3.启发式调度guided

  采用启发式调度方法进行调度,每次分配给线程迭代次数不同,开始比较大,以后逐渐减小。

  size表示每次分配的迭代次数的最小值,由于每次分配的迭代次数会逐渐减少,少到size时,将不再减少。如果不知道size的大小,那么默认size为1,即一直减少到1。具体采用哪一种启发式算法,需要参考具体的编译器和相关手册的信息。

三种运行方式总结:

静态调度static:每次哪些循环由那个线程执行时固定的,编译调试。由于每个线程的任务是固定的,但是可能有的循环任务执行快,有的慢,不能达到最优。

动态调度dynamic:根据线程的执行快慢,已经完成任务的线程会自动请求新的任务或者任务块,每次领取的任务块是固定的。

启发式调度guided:每个任务分配的任务是先大后小,指数下降。当有大量任务需要循环时,刚开始为线程分配大量任务,最后任务不多时,给每个线程少量任务,可以达到线程任务均衡。

OpenMP 中的线程任务调度的更多相关文章

  1. 并行计算之OpenMP中的任务调度

    本文参考<OpenMP中的任务调度>博文,主要讲的是OpenMP中的schedule子句用法. 一.应用需求 在OpenMP并行计算中,任务调度主要用于并行的for循环.当for循环中每次 ...

  2. [转]OpenMP中几个容易混淆的函数(线程数量/线程ID/线程最大数)以及并行区域线程数量的确定

    说明:这部分内容比较基础,主要是分析几个容易混淆的OpenMP函数,加以理解. (1)并行区域数量的确定: 在这里,先回顾一下OpenMP的parallel并行区域线程数量的确定,对于一个并行区域,有 ...

  3. .NET中的线程与异步(笔记)

    翻出了之前记录的笔记,基本涵盖了.NET中线程和异步的相关概念.可以提供一个学习的方向. 线程类型 工作者线程IO线程 线程池 全局队列(QueueUserWorkItem.Timer总是放入全局)本 ...

  4. Android中的线程池概述

    线程池 Android里面,耗时的网络操作,都会开子线程,在程序里面直接开过多的线程会消耗过多的资源,在众多的开源框架中也总能看到线程池的踪影,所以线程池是必须要会把握的一个知识点; 线程运行机制 开 ...

  5. [转]OpenMP中的private/firstprivate/lastprivate/threadprivate之间的比较

    转自:http://blog.csdn.net/gengshenghong/article/details/6985431 private/firstprivate/lastprivate/threa ...

  6. Android中的线程池 ThreadPoolExecutor

    线程池的优点: 重用线程池中的线程,避免因为线程的创建和销毁带来的性能消耗 能有效的控制线程的最大并发数,避免大量的线程之间因抢占系统资源而导致的阻塞现象 能够对线程进行简单的管理,并提供定时执行以及 ...

  7. OpenMP中的同步和互斥

    在多线程编程中必须考虑到不同的线程对同一个变量进行读写访问引起的数据竞争问题.如果线程间没有互斥机制,则不同线程对同一变量的访问顺序是不确定的,有可能导致错误的执行结果. OpenMP中有两种不同类型 ...

  8. Python之路-Python中的线程与进程

    一.发展背景 任务调度 大部分操作系统(如Windows.Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行.任务执行的 ...

  9. android中的线程池学习笔记

    阅读书籍: Android开发艺术探索 Android开发进阶从小工到专家 对线程池原理的简单理解: 创建多个线程并且进行管理,提交的任务会被线程池指派给其中的线程进行执行,通过线程池的统一调度和管理 ...

随机推荐

  1. bzoj 1898 矩阵快速幂

    思路:因为鱼的周期为2, 3, 4, 所以以12个为周期,我们拿走12步得到的矩阵进行快速幂,余下的再进行一次矩阵乘法. #include<bits/stdc++.h> #define L ...

  2. 五、oracle 表管理

    一.表名和列名的命名规则1).必须以字母开头2).长度不能超过30个字符3).不能使用oracle的保留字4).只能使用如下字符 a-z,a-z,0-9,$,#等 二.数据类型1).字符类char 长 ...

  3. Asp.net gzip压缩的启用

    gzip压缩使用一种压缩算法,对网页内容进行压缩,从而减小了网页体积.使用gizp压缩后减小了服务器的带宽.提高了网页的打开速度.下边看看我找到的一个asp.net中启用gzip压缩方案. 首先,我们 ...

  4. 超简教程:Xgboost在Window上的安装(免编译)

    Xboost在windows安装需要自己编译,编译的过程比较麻烦,而且需要复杂的软件环境.为了免去编译,我这里把编译好的文件上传到网盘供大家下载安装.有了编译好的文件,xgboost的安装变得超级简单 ...

  5. 初探Java字符串

    转载: 初探Java字符串 String印象 String是java中的无处不在的类,使用也很简单.初学java,就已经有字符串是不可变的盖棺定论,解释通常是:它是final的. 不过,String是 ...

  6. elementUI 学习入门之 inputNumber 计数器

    InputNumber 计数器 基础用法 <el-input-number v-model="num2"></el-input-number> v-mode ...

  7. JSP内置对象——request对象

    request对象request对象封装了由客户端生成的HTTP请求的所有细节,主要包括HTTP头信息.系统信息.请求方式和请求参数等. 通过request对象提供的各种方法可以处理客户端浏览器提交的 ...

  8. 使用matplotlib绘图(二)之柱状图

    # 使用matplotlib绘制柱状图 import numpy as np import matplotlib.pyplot as plt # 设置全局字体,以支持中文 plt.rcParams[' ...

  9. hibernate4日志配置

    在平时运行程序时控制台有很对的日志打印,本文说明如何控制这些日志打印. 1.确定要使用日志的实现,我在这使用的是log4j. 2.加入log4j的api包slf4j-api.jar,log4j的转换包 ...

  10. 【洛谷】2990:[USACO10OPEN]牛跳房子Cow Hopscotch【单调队列优化DP】

    P2990 [USACO10OPEN]牛跳房子Cow Hopscotch 题目描述 The cows have reverted to their childhood and are playing ...