本文参考《OpenMP中的任务调度》博文,主要讲的是OpenMP中的schedule子句用法。

一、应用需求

  在OpenMP并行计算中,任务调度主要用于并行的for循环。当for循环中每次迭代的计算量相差较大时,如果简单的为每次迭代分配相同的线程,就会导致线程任务不均衡,CPU资源没有被充分利用,影响程序执行性能。例如下面这种情况:

int i, j;
int a[][] = {};
for ( i = ; i < ; ++i )
{
for( j = i; j < ; ++j )
{
a[i][j] = i*j;
}
}

  很显然,如果对外层for循环做并行计算的话,那么i=0与i=99的计算量将相差100倍。为了解决这样的负载严重不均衡的情况,OpenMP提供了几种对for循环并行化的任务调度方案,schedule子句就是负责这样的任务的。

二、Schedule子句用法

  schedule子句的使用格式为:

schedule ( type [,size] )

  其中,type表示调度类型,可以有四种选择:dynamic、guided、runtime、static,其实runtime是根据环境变量来选择其他三种中的某一种类型;size是可选的,表示连续循环迭代的次数,必须为整数,当type为runtime时候不需要size参数。

2.1 静态调度(Static)

  当parallel for编译指导语句没有带schedule子句时,大部分系统中默认采用static调度方式,这种调度方式非常简单。假设有n次循环迭代,t个线程,那么给每个线程静态分配大约n/t次迭代计算。这里为什么说大约分配n/t次呢?因为n/t不一定是整数,因此实际分配的迭代次数可能存在差1的情况,如果指定了size参数的话,那么可能相差一个size。静态调度时可以不使用size参数,也可以使用size参数。

  举个例子来说:

#pragma omp parallel for schedule(static)
for (int i=; i<; ++i)
{
printf("i=%d, thread_id=%d\n", i, omp_get_thread_num());
}

  在我的四核笔记本上运行的结果如下(平均每个核心2.5次,结果显示最多相差1):

  如果添加一个size参数,就指定了连续迭代次数,比如这里指定size为2,将上面的语句修改为:#pragma omp parallel for schedule(static, 2),那么结果很快就变成了:

2.2 动态调度(dynamic)

  动态调度是动态地将迭代分配到各个线程,动态调度可以使用size参数也可以不使用size参数。不使用size参数时是将迭代逐个地分配到各个线程,使用size参数时,每次分配给线程的迭代次数为指定的size次。

  举个例子来看看四核CPU环境下的运行情况,将上面的语句修改为:#pragma omp parallel for schedule(dynamic),结果为:

  可以看出,这个调度是逐个将任务分配到每一个核心,然后哪个执行完了就接着分配。如果指定size为2,就会每一次为每一个核心连续分配两个任务,结果为:

2.3 guided调度(guided)

  guided调度是一种采用指导性的启发式自调度方法。开始时每个线程会分配到较大的迭代块,之后分配到的迭代块会逐渐递减。迭代块的大小会按指数级下降到指定的size大小,如果没有指定size参数,那么迭代块大小最小会降到1。

  将上面的语句修改为:#pragma omp parallel for schedule(guided),结果为:

  可以看出,采用这种调度方式时,第0、1、2次任务一次性分配给线程0,第3、4次任务分配给线程1,第5、6次任务分配给线程2,第7次任务分配给线程3(分配数衰减为1了),第8、9次任务分配给线程0(这里不是连续两次,而是因为线程0计算较快,重新分配了两个“一次任务”)。

2.4 runtime调度(runtime)

  runtime调度不是一种真正意义的调度方式,而是在运行时根据环境变量OMP_SCHEDULE来确定调度类型,最终使用的调度类型仍然是上述三种调度方式中的某种。 

  例如在unix系统中,可以使用setenv命令来设置OMP_SCHEDULE环境变量:setenv OMP_SCHEDULE “dynamic, 2”,此命令设置调度类型为动态调度,动态调度的迭代次数为2。
  在windows环境中,可以在“系统属性|高级|环境变量”对话框中进行设置环境变量。
 
小结:
  本文主要讲了OpenMP中的三种任务调度方式,用于灵活分配线程执行的for循环任务量。

并行计算之OpenMP中的任务调度的更多相关文章

  1. OpenMP 中的线程任务调度

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

  2. 并行计算之OpenMP入门简介

    在上一篇文章中介绍了并行计算的基础概念,也顺便介绍了OpenMP. OpenMp提供了对于并行描述的高层抽象,降低了并行编程的难度和复杂度,这样程序员可以把更多的精力投入到并行算法本身,而非其具体实现 ...

  3. Linux中的任务调度

    1.crond,linux中的任务调度器 crond的概念和crontab是不可分割的.crontab是一个命令,常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令.该命令从标准输入 ...

  4. Windows10环境中 laravel任务调度 如何启动调度

    Windows10环境中 laravel任务调度 如何启动调度 一:问题由来 1:今天在做用laravel开发订单系统的时候,需要使用定时任务来大批量提交订单,测试一下订单金额是否有误.发现larav ...

  5. OpenMP中的同步和互斥

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

  6. 聊Java中的任务调度的实现方法及比较

    前言 任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务.本文由浅入深介绍四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Quartz ...

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

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

  8. 关于MVC WebAPI 中加入任务调度功能的问题 (MVC WebAPI 任务调度)

    在MVC WebAPI中加入任务调度功能.即在MVC WebAPI启动时,启用任务调度程序. 但是这里有一个问题点,就是部署好IIS站点后,发现任务调度并没有启用.原因为何? 原因是部署好IIS站点后 ...

  9. spark中资源调度任务调度

    在spark的资源调度中 1.集群启动worker向master汇报资源情况 2.Client向集群提交app,向master注册一个driver(需要多少core.memery),启动一个drive ...

随机推荐

  1. 错误处理:加载文件或程序集“ICSharpCode.SharpZipLib”

    解决方案:如果你的程序是2.0的,则删除 C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/中的所有的文件 如果是4.0的,删除C:/WINDOWS/Micr ...

  2. spring和redis的整合-超越昨天的自己系列(7)

    超越昨天的自己系列(7) 扯淡:  最近一直在慢慢多学习各个组件,自己搭建出一些想法.是一个涉猎的过程,慢慢意识到知识是可以融汇贯通,举一反三的,不过前提好像是研究的比较深,有了自己的见解.自认为学习 ...

  3. GFF format

    后记: ************************************************************************ 在使用cufflinks和cuffmerge中 ...

  4. Apache HttpClient使用之阻塞陷阱

    前言: 之前做个一个数据同步的定时程序. 其内部集成了某电商的SDK(简单的Apache Httpclient4.x封装)+Spring Quartz来实现. 原本以为简单轻松, 喝杯咖啡就高枕无忧的 ...

  5. 转载:LBP的初步理解

    转自http://blog.csdn.net/ty101/article/details/8905394 本文的PDF版本,以及涉及到的所有文献和代码可以到下列地址下载: 1.PDF版本以及文献:ht ...

  6. codeforces 192 D

    link: http://codeforces.com/contest/330/problem/D The discription looks so long, but the problem is ...

  7. codeforces magic five --快速幂模

    题目链接:http://codeforces.com/contest/327/problem/C 首先先算出一个周期里面的值,保存在ans里面,就是平常的快速幂模m做法. 然后要计算一个公式,比如有k ...

  8. C与Python变量的区别

    C中变量有类型,代表一定内存. 而Python变量只是封装过的指针,没有类型.如果不指向对象,就没有意义,更谈不上类型. python中 a=b,和C中 a=b是完全不同的两个操作.前者只是指针(引用 ...

  9. Codeforces Round #145 (Div. 2, ACM-ICPC Rules)

    A. Lefthanders and Righthanders \(i\)与\(i+\frac n2\)匹配,根据左右手调整位置. B. Reading 排序,取前\(k\)个. C. Weather ...

  10. PHP内存消耗

    由于变量占用的空间不一样,所以其消耗的内存大小也不一样,在PHP中我们可以通过使用“memory_get_usage”来获取当前PHP消耗的内存.但是根据操作系统.PHP版本以及PHP的运行方式可能输 ...