设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 开源资讯 查看内容

OpenMP 4.5的新特性

2016-7-28 22:36| 发布者: joejoe0332| 查看: 2706| 评论: 0|原作者: oschina|来自: oschina

摘要: 2015年11月 新的 OpenMP 4.5 标准已经被释放了。(OpenMp是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的,用于共享内存并行系统的多处理器程序设计的一套指导性的编译处理方案(Compiler Directi ...
2015年11月 新的 OpenMP 4.5 标准已经被释放了。(OpenMp是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的,用于共享内存并行系统的多处理器程序设计的一套指导性的编译处理方案(Compiler Directive)并且有多个新的结构体带给用户。OpenMP API由编译器指令和库例程组成高度并行于 C, C++ 和 Fortran 项目. 即将更新的GCC版本为最近版的标准添加了支持。 

本文高亮了一些最新特性,以及众所周知的地方方便查看

Taakloop construct(任务循环结构)

咱们马上开始,这个“任务循环”结构是被新添加到4.5版本之中的,如名所示,允许分割迭代循环到任务,它能随意的等待完成哪些任务并且每个被创建的任务都可以分配1个或多个迭代循环。例如:

1
2
3
#pragma omp taskloop num_tasks (32)
  for (long l = 0; l < 1024; l++)
    do_something (l);

上面的代码将在一个任务组中创建32项相互关系的任务,还有一项合理的实施就是给每项任务分配32次迭代。因为有一个隐式的课题在那里面,我们遇到的任务将依赖其它所有任务的完成。在OpenMP 4.0和更早的版本里,为了实现类似的效果,我们必须手动完成那些任务,像下面的例子:

1
2
3
4
5
6
7
#pragma omp taskgroup
{
  for (int tmp = 0; tmp < 32; tmp++)
    #pragma omp task
      for (long l = tmp * 32; l < tmp * 32 + 32; l++)
        do_something (l);
}

当代码中有很多死循环或者如果在循环中使用C++迭代器时,我们手动处理将会变得越来越困难,所以运用任务循环概念将会大大简化代码源。我们可以使用grainsize措施,而不是指定我们应该创建的任务数目。它指定了每项任务中应该有多少次的迭代(从指定的grain-size到小于它两倍的值),并且这个措施可以自动计算任务的的数目。另外,如果num_tasks和grainsize选项都不见了,这个措施里会选择一些适宜的默认选项。

OpenMP4.5中另一个任务分配的改变是增加了任务优先级, 可以用priority子句指定任务的优先级。正如你所预见的,任务优先级更高的任务将被优先调度。

交叉并行

一些样例考虑对有内部迭代依赖的循环进行并行化。这通常是可行的,只要并行工作的线程不会花费大部分的时间等待其他线程。

OpenMP 4和更早的版本提出的“有序”的构建。在一个循环结构中,以一个ordered子句为标记,将有序结构的主体在循环中执行。OpenMP 4.5可以使用命令(无本体)表示依赖于以前版本的迭代循环,所有其他的迭代可能取决于一个迭代的数据计算。例如:

1
2
3
4
5
6
7
8
9
10
#pragma omp for ordered(2)
  for (int i = 0; i < M; i++)
    for (int j = 0; j < N; j++)
      {
        a[i][j] = foo (i, j);
        #pragma omp ordered depend (sink: i - 1, j) depend (sink: i, j - 1)
        b[i][j] = bar (a[i][j], b[i - 1][j], b[i][j - 1]);
        #pragma omp ordered depend (source)
        baz (a[i][j], b[i][j]);
      }

以上的例子表明,只有外部循环分布在一组线程中。第一个ordered的指令告诉运行时等待指定的早期迭代完成,而最后一个ordered的指令标志着循环计算出的所有数据的其他循环可能存在依赖。

在这个例子中,编译器会忽视 depend (sink: i, j - 1) 依赖,因为外部循环参与了工作负载,内部循环使用字典顺序迭代;因此,等到 i, j 迭代被执行的时候, i, j – 1迭代肯定就完成了。

除了允许 depend 子句在命令指令中,OpenMP 4.5 还一直允许 threads 和 simd 子句有序构造,还允许 在 SIMD 循环中使用  #pragma omp ordered simd 。这标志着在字典顺序执行代码的区域内 SIMD 循环,对于一小部分代码,不应向量化的 vectorizable 循环。

数据共享变更

包括最新的更新,C++参考现在在私有化条款中已经被允许,以前他们只允许共享条款。

C++的方法中,对象的方法调用时,现在对它的非静态数据成员进行私有化访问是有可能的,只要在相应的OpenMP区域中通过使用id-expression(id表达式)来访问,而非显式使用this->memeber来引用。

C和C++中的reduction clause(reduction语块)允许数组区间,因此C/C++的数组可以reduction而无须包装为结构体或是类,也不需要定义用户所定义的reduction。 linear clause(线性语块)现在可以用在循环体中,而此前只允许在SIMD结构中使用。

卸载(Offloading)的变化

Offloading 可能是OpenMP标准中变化最大的部分, 由此引入一了些代码级别的不兼容——这些大多与scalar变量的非显式的引用有关,如C/C++对像区域中的指针!

OpenMP 4,这些变量,除非明确在地图条款提到建设目标,进行隐式映射从–意味着指针的主机端值将被复制到目标(通常是不是真的有用,有一个指针)目标值复制到主机(通常也不受欢迎),或最后没有复制如果变量已经映射。

OpenMP 4.5,除非defaultmap(来自:标量)条款使用标量变量是隐式的私有化,如果新firstprivate条款允许建设的目标是让他们使用–意义的值都复制到目标区域,并没有复制回。
在许多情况下,甚至会用OpenMP 4的代码编写工作,但异常主要是如果你需要一个标量值从装置在目标区域的结束。例如,下列OpenMP 4将不再工作:
 

1
2
3
4
5
6
7
8
void foo () {
  double sum = 0.0;
  #pragma omp target map(array[0:N])
  #pragma omp teams distribute parallel for simd reduction(+:sum)
    for (int i = 0; i < N; i++)
      sum += array[i];
  return sum;
}

失败会因为金额将在该地区firstprivate和主机的值不会被修改。港口代码OpenMP 4.5,需要添加default(tofrom: scalar)条款的目标区域,或使用显式的map(tofrom: sum)

指针是隐式映射为如果他们出现在地图map(ptr[:0])条款–因此主机指针转化为相应的设备指针如果指向的对象已经映射,或空否则。

C++引用映射已澄清,它现在是可能的地图结构元素单独。异步卸载支持已被添加通过立即和依赖条款对目标构建的,而在OpenMP 4.0,所有目标区域进行同步–主机的任务会等待直到卸载完成后,和一个有使用主机来实现异步任务手动卸载。
 

目标结构现在被视为一个隐式的任务区域,并添加新的目标输入数据和目标退出数据结构。这意味着映射和映射变量联合国现在可以进行同步或异步,和在不同的函数或方法–例如可以输入数据在C++构造函数和出口数据在C++析构函数。

声明目标指令已被扩展,并且现在可以标记为延迟映射的全局变量(例如大数组)。设备内存例程已经添加显式分配,分配和内存传输主机和卸载设备之间,以及与本地设备实现交互的条款被加入:use_device_ptr条款目标的数据结构和is_device_ptr条款目标构建。

GCC 6目前支持卸载英特尔XeonE5骑士着陆,一些OpenMP 4.5目标构建可卸载到AMD HSA GPGPU,OpenMP卸载Nvidia PTX在作品(OpenACC卸载Nvidia PTX已经支持)。
 

其它改进

在OpenMP 4.5 中还有一些较小的改进,包括:

提升了对Fortran 2003 的支持。

关键架构和新提示锁API例程添加了一个hint子句,它允许应用通知运行时资源争用和猜测的必要性。

扩展了if子句,当使用组合和复合构造时,可以指定if子句应用的构造,并且可以对不同构造指定不同的if子句。

在#pragma omp declare simd指令的线性子句中,现在可以通过val,uval和ref修饰指定,不管引用是线性的或引用的变量值是线性的。

查询的线程相关性已经被添加。

在现实中,OpenMP 4.5还包含其他各种小变化,列出了很多说明和bug修复,但是更值得注意的是其中一些总结。

尝试

OpenMP 4.5的新版本标准可以从http://www.openmp.org/mp-documents/openmp-4.5.pdf得到,新版本支持即将到来的GCC 6(仅供C和C++。)

Fortran支持的仍然是OpenMP 4.0这个级别的版本,并且计划在今年4月左右发布。


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部