《OpenACC并行程序设计:性能优化实践指南》一 1.4 并行执行和竞争条件

1.4 并行执行和竞争条件

OpenACC并行化for循环(Fortran中是do循环),因此循环内的代码使用并发硬件执行线程并行执行。
循环内的变量i似乎是顺序递增的,但实际上在这个for循环中使用多个i变量的线程可能同时并行执行,这可能有点令人困惑。OpenACC不保证线程执行的顺序,注意这点非常重要。实际上,甚至不可能假设单调性。例如,很有可能第nCount―1次迭代实际上先于第0次迭代执行完。
OpenACC不保证线程执行的顺序,注意这点非常重要。
总之,OpenACC编程人员不能也不应该对线程执行的顺序做任何假设,如图1-15所示。

竞争条件
并行循环中线程之间的数据依赖性可能会给OpenACC编程人员带来问题,尤其是OpenACC除了原子操作外不提供任何锁机制来防止竞争条件。当多个线程相竞对一个共享数据项执行某个操作,这会导致竞争条件。除非在另一个线程可以访问这个共享数据项之前开始并且执行完操作,例如原子处理写或写后读操作,否则操作结果是未定义的。(注意:对只读数据项不存在竞争条件。)
如图1-16所示,以粗体显示的并行更新计数器发生共享数据依赖。当通过counter++更新时,示例使用#pragma acc atomic update来保护counter变量。在OpenACC中,使用原子读、写或者更新语法可以保护单个变量。示例使用条件编译,所以可以看到如果忽略原子操作结果会是什么。

图1-16 accCounter.cpp:包含竞争条件的示例
因为编程人员不能控制线程的执行顺序,因此不包含原子语法是一个常见的错误。这将产生竞争条件,从而导致垃圾和不确定性结果。非确定性行为是非常危险的,因为程序可能在调试时报告看起来是正确的结果,但是在产品中失败了。此外,应用程序可能在一个平台上正常执行,但在另一个平台上失败,或者使用特定软件版本时正确执行,然后软件更新后执行失败。
当遗漏原子操作时,PGI OpenACC编译器可以智能地检测示例中的错误。如图1-17中的粗体所示,编译器决定使用一个线程来生成串行代码,以确保正确性。下面的信息给出了原因,即变量counter在循环外生存。简单地说:变量保存了将来可能需要的值且编译器的数据流分析确定退出代码块时其他语句需要这个变量,这种情况下变量还生存着。精确的生存时数学定义超出了本章的讨论范围,感兴趣的读者可以阅读关于编译器数据流分析的文章以作了解。

定义USE_ATOMIC宏,在编译时包含OpenACC原子语法。在accCounter.cpp示例中,PGI编译器为GPU生成一个并行内核,为CPU生成多核循环。命令行参数nvidia:cc35告诉编译器目标设备为NVIDIA 3.5计算能力。这么做是为了看到更高效的现代GPU原子操作对运行时的影响,因为计算能力2.x(例如,费米)和更高版本的GPU具有更高效的原子操作。虽然原子操作方便,但还是要避免使用它们。因为每次只有一个线程可以访问原子变量,所以它们在运行时强制串行化。accCounter.cpp示例是一个糟糕的应用场景,因为每个线程必须排队来执行counter++的操作。
如图1-18所示,编译器报告生成了并行代码。由于对counter变量的竞争操作致使并行代码性能随着问题规模线性增长。如图1-19所示,相比串行代码,由于线程和原子操作的间接开销,并行代码运行时间更长。

如图1-20所示,在NVIDIA Tesla K40(计算能力3.5)GPU上串行版本运行时随着问题规模线性增长。与此同时,并行版本运行时比较稳定。这是因为NVIDIA对硬件做了优化,这些优化使得一些原子操作适用于大规模并行计算环境。更多信息,建议阅读《GPU大规模并行处理的大规模原子操作》(Egielski, Huang, &Zhang, 2014)和《NVIDIA费米:第一个完全GPU计算架构》(Glaskowshy, 2009)。

时间: 2024-10-02 19:57:58

《OpenACC并行程序设计:性能优化实践指南》一 1.4 并行执行和竞争条件的相关文章

《OpenACC并行程序设计:性能优化实践指南》一 导读

前言 欢迎阅读本书,这是一本由浅入深的书籍,从初学者到高级开发人员,都可以通过本书了解OpenACC的相关知识.本书由世界各地的24位作者共同编著而成,他们在高度并行编程的教学和实践方面分享了自己的专业知识.书中的例子既有时效性又不会过时.每个章节都是自包含的,可用于自学,也可以作为课堂教学的一部分. 这是一本关于并行编程的书,不仅仅介绍OpenACC语法或从文档中收集的信息,更介绍了如何编写实际的.高性能的以及可移植的程序,这些程序可以运行在从CPU到GPU的大量设备上.具体而言,书中演示了使

《OpenACC并行程序设计:性能优化实践指南》一 1.1 简单的数据并行循环

1.1 简单的数据并行循环 在顺序处理器程序设计中,需要编写计算某个最终结果所需要的任务和数据操作的程序.通过创建OpenACC,编程人员可以插入编译指令给编译器提供信息,而这些编译指令是关于并行机会和数据在加速器与主机间来回传输的信息.结合编译器,程序员使用注记来创建.调试和优化并行代码,使得程序达到高性能. OpenACC帮助程序员编写高效的数据和任务并行软件. 数据并行关注跨多个并发执行线程的分布式数据操作.在计算机科学中,线程是串行执行一段代码的线程的缩写.通过使用多个线程,应用程序可以

《OpenACC并行程序设计:性能优化实践指南》一 1.3 Amdahl定律及其扩展

1.3 Amdahl定律及其扩展 绘制任务运行时间,可以看到并行增加应用程序的扩展行为.并行计算的理论性能:运行在有N个处理单元的并行计算机上,理论上可以获得N倍加速.换一句话说,一个程序运行在10核处理器上可能获得10倍加速(对于固定大小的问题),在支持1000个并发执行线程的GPU上获得1000倍加速.开发人员依据Amdahl定律来讨论并行与串行间的加速比. 用计算机架构师Gene Amdahl来命名Amdahl定律.它不是实际上的定律,但是修改串行程序使其并行执行时,它相当接近模型理论加速

《OpenACC并行程序设计:性能优化实践指南》一 2.6 小结

2.6 小结 OpenACC是一种描述型并行编程模型.在本章中,通过一个测试函数的应用,使用了OpenACC的多种特性来描述并行度和数据操控,并针对特定平台对代码进行了优化.尽管使用的是PGI编译器和PGProf性能调试器,但类似的优化流程也是适用于任何支持OpenACC工具包的应用的. 1.获得应用程序的性能分析结果,辨识和挖掘代码中的可并行之处. 2.逐步向编译器描述代码中可挖掘出的并行性.如果主机端和设备端使用各自的存储器,这一步骤后获得的代码很可能会减速. 3.描述应用程序的数据移动.编

《OpenACC并行程序设计:性能优化实践指南》一 3.2 逐步性能提升

3.2 逐步性能提升 本书的示例表明,通过提交更多的活动和优化数据传输,使用性能分析驱动的开发可不断提升OpenACC应用程序的性能.图3-2列出了优化混合应用遵循的模式. 从应用准备开始性能优化周期,然后进行实际的性能测量,并对性能数据进行分析.基于这些数据,编程开发人员尝试减少性能问题,并重新开始整个过程.下面使用Score-P和Vampri讲解性能提升周期里的前三步,以CUDA加速粒子单元模拟为例,其中CUDA部分代码很容易用OpenACC实现代替来获得同样的结果.此外,还引入了各种优化步

《OpenACC并行程序设计:性能优化实践指南》一 第1章 从串行编程到并行编程

第1章 从串行编程到并行编程 Rob Farber TechEnablement.com CEO/创始人 本章主要向读者介绍OpenACC,演示如何使用OpenACC编写运行在多核CPU和类似GPU加速器上的可移植并行程序,并展示如何在CPU和GPU上编译和运行OpenACC程序. 阅读本章后,读者将会理解以下内容: 如何创建.编译和运行OpenACC应用程序. 高性能OpenACC编程的三个准则. 数据并行和任务并行编程的基本概念. 理解大O表示法和Amdahl定律. 竞争条件.原子操作,以及

《OpenACC并行程序设计:性能优化实践指南》一 1.5 无锁编程

1.5 无锁编程 互斥锁是用于同步进程或线程的常用机制,这些进程或线程需要访问并行程序中的一些共享资源.互斥锁就像它们名字所说的:如果一个线程锁住了资源,另一个线程希望访问它需要等待第一个线程解锁这个资源.一旦资源被解锁,第二个线程在处理这个资源时会一直锁住它.程序的线程必须遵守:一旦使用完共享资源尽快解锁,以保持程序执行流程. 由于OpenACC中没有锁,编程人员需要熟悉无锁编程和数据结构的概念.无锁方法保证至少一个执行该方法的线程的进展.可能存在某些线程可以被延迟的情况,但是保证至少一个线程

《OpenACC并行程序设计:性能优化实践指南》一 第3章 使用Score-P和Vampir分析混合应用性能

第3章 使用Score-P和Vampir分析混合应用性能 Guido Juckeland 德国亥姆霍兹联合会(HZDR)信息服务和计算机系 Robert Dietrich 德国德累斯顿工业大学 本章的目的是让读者熟悉逐步性能提升的概念,以及在向OpenACC应用程序添加其他并行模式时所涉及的工具.混合应用程序可能会遭受许多性能瓶颈,应用程序运行期间所有活动的整体图可以揭示如何提高整体性能. 阅读本章后,读者将会理解以下内容: 混合应用程序(例如,MPI+OpenACC)性能分析的术语和方法. 如

《OpenACC并行程序设计:性能优化实践指南》一 2.5 在多核系统中并行运行

2.5 在多核系统中并行运行 尽管本章使用了NVIDIA GPU,但OpenACC不是一个GPU编程模型,而是一种普遍适用的并行编程模型.尽管在2.4节中使用的循环优化技术仅适用于GPU,关于并行度和数据移动的技术手段适用于任意并行架构设备.本章使用的PGI编译器支持多种目标加速器,包括NVIDIA和AMD公司的GPU,以及多核x86 CPU.如果在多核CPU上开发和运行代码,将会发生什么呢?为多核目标平台重新编译代码,而不是将目标设定为tesla(见图2-29和图2-30). 如果运行可执行程