OpenACC 高性能并行编程:概念与策略 (21):循环级并行性 2.3.2

阅读数:1 2020 年 1 月 5 日 18:32

OpenACC高性能并行编程:概念与策略(21):循环级并行性 2.3.2

(independent 子语)

内容简介
本书是介绍大规模并行编程 OpenACC 的综合实践性书籍之一。书中前 3 章介绍了 OpenACC 背后的概念和 OpenACC 开发工具;第 4 章至第 7 章带你了解第 1 个真实世界的 OpenACC 程序,并揭示 OpenACC 程序编译背后的魔力,从而引入更多概念;第 8 章至第 10 章涵盖高级主题,例如 OpenACC 的替代方案、底层设备交互、多设备编程和任务并行性;第 11 章和第 12 章探讨了 OpenACC 实现潜在新语言特性的各种研究领域。

OpenACC 的大部分功能是基于编译器分析代码,并推算出它是否可以安全地并行化(例如,kernel 区域),但是编译器并不是每次都有足够的信息来正确地做出这一决定。

因此,编译器在决定哪些循环可以并行化时经常会出错,这可能意味着代码中的性能损失。因为功能可以跨越许多线程运行,运行功能时是按顺序执行这些线程的。下面是这种代码的一个例子:

OpenACC高性能并行编程:概念与策略(21):循环级并行性 2.3.2

这段代码最内层循环中的代码依赖于外层循环计数器(用于计算 local_index),因此编译器认为这是循环依赖(即循环的一次迭代依赖于前一次迭代的结果)。最终结果是编译器生成一个顺序 kernel,而不是并行化循环。你可以通过在 loop 导语中添加 independent 子语来解决这个问题,告诉编译器需要保证循环迭代之间是互相独立的,这样编译器就能够安全地并行化循环了。

请注意,此问题不限于 OpenACC 或加速器应用程序,编译器在尝试向量化代码时也有类似的问题。许多编译器或并行编程方法将会提供一些方法,让编译器了解更多有关循环的信息,以帮助编译器将迭代分配给并行硬件。

independent 子语仅适用于 kernel 区域中的循环,因为 parallel 导语已经通知编译器 parallel 区域中的所有循环都是独立的,除非它们明显地包含一个 seq 子语。

一般来说,在 kernels 区域中,没有必要将 independent 子语添加到所有循环中。这主要是在使用 OpenACC 并行化代码之后的优化步骤。

通常情况下,通过分析编译器关于并行性实施的报告,或者通过对应用程序上的数据做性能分析,你能找到没有被并行化的循环。如果分析发现这些循环之间确实互相独立,此时再添加 independent 子语。

以 PGI 编译器为例,在编译代码时使用 -Minfo=accel 选项,可能会得到以下输出:

OpenACC高性能并行编程:概念与策略(21):循环级并行性 2.3.2

类似的输出表明,相关的代码循环还需要进一步研究是否可以并行化。

OpenACC高性能并行编程:概念与策略(21):循环级并行性 2.3.2

购书地址 https://item.jd.com/12596484.html?dist=jd

评论

发布