CN102981807B - 一种基于cuda并行环境的gpu程序优化方法 - Google Patents
一种基于cuda并行环境的gpu程序优化方法 Download PDFInfo
- Publication number
- CN102981807B CN102981807B CN201210444220.4A CN201210444220A CN102981807B CN 102981807 B CN102981807 B CN 102981807B CN 201210444220 A CN201210444220 A CN 201210444220A CN 102981807 B CN102981807 B CN 102981807B
- Authority
- CN
- China
- Prior art keywords
- instruction
- bottleneck
- program
- cuda
- gpu
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Landscapes
- Devices For Executing Special Programs (AREA)
Abstract
本发明涉及一种基于CUDA并行环境的GPU并行程序优化方法,定义了GPU程序内核的性能瓶颈,根据级别包括全局储存器访问延迟、共享存储器访问冲突、指令流水线冲突、指令瓶颈。并为每个性能瓶颈提出实际可操作的判定标准和瓶颈优化解决方法:全局储存器访问延迟优化方法:转存共享存储器、访问归并、提高线程级并行度、提高指令级并行度;共享存储器访问冲突和指令流水线冲突优化方法:解决bank conflict,转存寄存器、提高线程级并行度、提高指令级并行度;指令瓶颈:指令替换和减少分支。本发明为CUDA程序编写和优化提供依据,帮助程序编写者方便得找到CUDA程序中的性能瓶颈,并针对性能瓶颈做出高效有针对性的优化,使得CUDA程序可以更大限度的发挥GPU设备的计算能力。
Description
技术领域
本发明涉及一种图形、动画、科学计算、地质、生物、物理模拟等诸多领域的并行计算与数据处理方法,特别涉及一种基于CUDA架构的GPU内核程序优化方法,属于高性能计算领域。
背景技术
CUDA架构(Compute Unified Device Architecture)是面向GPU(Graphic ProcessingUnit)图形处理器等设备的并行计算架构,是一套在GPU上完成高性能计算的解决方案,在CUDA环境上并行编程的接口API有CUDA C,C++,OpenCL,RapidMind等。CUDA C是基于CUDA架构的C语言扩展,程序编写者可以方便的利用这套API进行GPU编程。而程序的效果实现则依赖于程序员编写性能高效、功能稳定和可移植性强的CUDA内核程序,CUDA内核程序又被称为kernel函数,是在GPU上运行的并行计算函数,内核程序的性能直接反映了程序对设备计算资源的利用情况。
目前针对CUDA内核程序的优化存在一些较为成熟的技术,本发明重点整理了以下内容:
背景技术一:CUDA的技术手册(CUDA的技术手册以NVIDIA.CUDA C Best Practices Guide.January 2012.为主)上公布了对存储器访问、处理器资源利用以及指令优化的一些技术。在这套手册中,强调了两部分内容:一是通过提高以SM设备占有率为指标的程序并行度来掩盖指令执行时遇到的延迟问题;二是对以全局存储器访问为代表的存储器访问模式进行较深入的优化。但是,这些优化技术的不足在于过多的考虑设备占有率对程序性能的影响,其提出的程序并行度也主要是线程级并行(TLP:Thread Level Parallelism),而没有提及指令级并行(ILP:Instruction Level Parallelism)这一优化CUDA程序性能的重要技术;同时,CUDA技术手册在考虑程序延迟时轻视了全局存储器延迟外的其它延迟,这些延迟成为程序进一步优化工作中的重点。
背景技术二:NVIDIA公司的王鹏博士提出了一套较为完整的CUDA程序优化流程,(PengWang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.)将性能瓶颈分为存储器瓶颈、指令瓶颈和延迟瓶颈,并给出了具体的瓶颈解决方法。但是,这套优化流程所给出的瓶颈判定标准不够清晰明确,如指令瓶颈的判定仅有两条:1.计算密集型程序很容易成为指令瓶颈;2.将指令优化放在存储器优化和延迟优化之后等(具体可参见文献PengWang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.);同样,在这套优化流程中也没有提到ILP优化和非全局存储器访问的延迟问题。
背景技术三:伯克利大学的Volkov在2010年GTC大会上对CUDA程序在低占有率下使用指令级并行的优化方案进行了论述Vasily Volkov,Better Performance at Lower Occupancy,GTC 2010,UC Berkeley,September 22,2010,提出了可以在较低的占有率下进行CUDA程序优化,并给出具有优化效果的程序样例。Volkov在之后的另外两篇文献Vasily Volkov,Use registers and multiple outputs per thread on GPU,UC Berkeley,PMAA’10,June30,2010和Vasily Volkov,Unrolling parallel loops,UC Berkeley,tutorial talk SC11,November 14,2011中对指令并行如何操作做了进一步的解释。但是,这些文献中都没有对指令集并行优化的场合和条件做出限定,这一技术与实际应用仍有距离。本发明认为指令级并行并不适合所有的代码,并首次对指令并行使用的场合和条件做出严格限定。
上述这些公开的优化技术都只局限于CUDA程序优化的几个方面,不足以充分发挥GPU设备的运算能力,实际达到的优化效果也不够完善;同时,这些文献或作者往往没有给出技术的理论阐述,对优化技术的使用场合和条件解释的不清楚,因此很难达到实际可操作的标准。在实际编写的大量CUDA程序中,性能的优化工作往往是不够的,要求更多的程序员可以快捷的掌握CUDA程序的编写和优化技术而不止是让技术停留在研究层面。
因此,提出一套完整的实际可操作的,具有较强通用性和优化效果的技术流程是本领域亟待解决的技术问题。
发明内容
针对目前已公开的优化技术现状,本发明提供了一种实际可操作的CUDA内核程序性能优化解决方案,从性能瓶颈的判定到优化方法的选取,再到优化技术的具体实施给出详细方案和步骤,为CUDA程序编写和优化提供依据,帮助程序编写者方便得找到CUDA程序中的性能瓶颈,并针对性能瓶颈做出高效有针对性的优化,使得CUDA程序可以更大限度的发挥GPU设备的计算能力。
本发明所使用的CUDA架构软硬件特性资料主要引自本领域较权威的技术指南《GPU高性能运算之CUDA》(张舒,褚艳利等编著,中国水利水电出版社2009年)以及NVIDIA公司提高的CUDA C编程手册(NVIDIA.CUDA C Programming Guide.January 2012.)。目前市场上支持CUDA的GPU设备规格不尽相同,本发明以设备计算能力设备计算能力是衡量GPU设备对CUDA支持能力的指标,较高级的版本会继承发展较低级版本的全部特性并增添新的功能2.1的GF114子架构,GF114架构是Fermi 2.0架构的典型代表,该架构的GPU是目前硬件市场的主流产品。
在本发明中以该设备为例具体说明,并且尽可能的兼顾其它版本的计算能力。
本发明技术方案如下:一种基于CUDA并行环境的GPU程序优化方法,其步骤包括:
1)根据CUDA上的程序分析工具对GPU程序进行检测,得到程序需求占有率并判断此时程序是否存在全局存储器访问瓶颈,同时对所述全局存储器访问瓶颈进行消除,进入步骤2);
2)根据共享存储器中bank-conflicts访问冲突的数目判断所述步骤1)的GPU程序中是否存在共享存储器访问瓶颈,同时消除所述共享存储器访问瓶颈和新生成的全局存储器访问瓶颈,进入步骤3);
3)使用CUDA的程序分析工具在所述步骤2)的GPU程序提取出性能参数,综合分析判断是否存在流水线指令执行依赖瓶颈并消除该指令流水线冲突,得到实际IPC可达到指令瓶颈IPC的GPU程序进入步骤4);
4)在所述步骤3)中若GPU程序实际IPC达到指令瓶颈IPC,则进行指令瓶颈优化处理;
5)重复遍历以上步骤1)—4),直至所述GPU程序不存在上述步骤2)-4)中的任意一项瓶颈并且程序性能提升满足用户需求,完成GPU程序优化过程。
所述程序需求占有率α=Na/48=(Nm/Ni)*T/48,其中Na为active warp数目,T为一次访问存储延迟,Nm/Ni为访问存储请求次数与指令数目之比。
所述全局存储器访问瓶颈判断方法是:若实际占有率不能满足需求占有率,则GPU程序中存在全局存储器访问瓶颈,所述实际占有率可以通过CUDA程序分析工具中ParrallelNsight的CUDA Memory Statistics和Instruction Statistics读出;所述共享存储器中bank-conflicts访问冲突的数目通过Parrallel Nsight的CUDA Memory Statistics中得出。
所述步骤1)重复直至实际占有率大于需求占有率,消除所述步骤1)中全局存储器访问瓶颈的优化方法包括:提高线程级并行度、提高指令级并行度、全局存储器转存共享存储器、全局存储器访存归并。
所述步骤2)中共享存储器访问瓶颈消除方法为:改进共享存储器的访问任务分配解决bank-conflicts访问冲突和/或共享存储器转寄存器。如果存在共享存储器bank-conflict,优先解决bank-conflict,如果每个线程处理彼此无关任务,可以将访问不同bank的线程放在同一个warp内;当不可避免的需要访问同一个bank内部的数据时,考虑这部分数据的大小以及需要在线程间通信等因素,将这部分共享存储器的数据转存在寄存器中,可以考虑减少SM上线程的数目来获取额外的寄存器资源。
所述流水线指令执行依赖瓶颈优化处理为提高线程级并行度和/或提高指令级并行度。
当GPU中存在复杂的逻辑控制,每个线程的任务不尽相同,或者存在大量不可预测的分支跳转时,可以考虑增大SM的占有率,利用更多的线程级并行来掩盖指令流水线延迟;
当GPU程序出现重复大量无关的相同工作如对存储器访问时,考虑将多个无关的任务分配给单独的线程来处理,利用更多的指令级并行解决依赖冲突。
所述指令瓶颈优化处理为:如果程序中存在影响warp分支的分支跳转,优先将这部分工作移到同一个warp或者相邻的线程中,或者高吞吐量指令替换低吞吐量指令和/或减少指令分支。
所述步骤3)中流水线指令执行依赖瓶颈从GPU程序中Parrallel Nsight分析工具的Issue Stalls Tab得到,基于Warp Issue Efficiency饼状图中eligible warp的数目和/或Issue Stall Reasons饼状图中Execution Dependency所占的比例。
对部分程序所述全局存储器访问瓶颈的判断方法可采用存储器访问替换的方法:保留在全局存储器访问时使用的索引计算,通过改变全局存储器访问,观测程序执行时间发生的变化。
所述改进共享存储器的访问任务时将共享存储器的维度定义为warp数目加一,并按照线程所在warp中的ID来访问共享存储器。
本发明的有益效果
本发明在现有文献的基础上,改进和发展了诸多CUDA内核优化技术,明确定义了内核的性能瓶颈,并为每个性能瓶颈提出实际可操作的判定标准,利用方便的性能分析工具得到性能指标,辅助瓶颈判定,并提出了新的对于诸多优化技术的使用条件,在上述内容的基础上完成优化流程的设计。为CUDA程序编写和优化提供依据,以尽量小的代价获取更高的设备性能。
附图说明
图1是本发明基于CUDA并行架构的GPU程序优化方法针对不同瓶颈采用相应的优化方法。
图2是本发明基于CUDA并行架构的GPU程序优化方法中一实施例的优化流程图。
具体实施方式
发明原理
CUDA并行程序的性能依赖于多种因素,各自的因素都会使得程序的执行时间存在一个特定的下限,而最终程序的执行时间取决于下限中最低的一个。在已公开的文献中大都提及到了CUDA程序的性能瓶颈或者性能优化点。本发明仍然采用性能瓶颈的优化模式,为了达到优化程序性能的目的,首先要为广泛的程序性能瓶颈给出定义(本发明可能涉及与现有文献中相同或类似的性能瓶颈,但定义与现有文献给出的定义不完全相同)。
GPU设备的处理器在运行过程中仅会处于两种状态:执行指令流水线和等待延迟,执行指令使设备的计算资源得到了利用,而等待延迟则浪费了设备的计算能力。本发明的优化方法将主要的性能瓶颈按照优先级(可参考NVIDIA.CUDA C Programming Guide.January 2012.和Peng Wang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.等)分为以下四类:全局存储器访问瓶颈、共享存储器访问瓶颈、指令执行依赖瓶颈和指令瓶颈。虽然除此之外仍存在其它因素,诸如指令获取延迟(指令的获取实际上是和全局存储器访问一样耗时的操作,但由于指令缓存的存在(具体指令缓存可参见文献张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.),在性能优化中这一部分的因素常常被忽略、线程同步延迟(线程同步或线程通信是CUDA程序中常见的操作,但针对不同的程序线程同步的影响差别很大,同时由于线程同步是保证程序正确性所必不可少的,CUDA程序优化将其作为次要因素)等影响程序性能,但这四个因素是影响最大的。以下列出各种程序瓶颈产生的原因。
1.全局存储器(全局存储器是在显存上最大块的存储器,通常在内核程序运行前动态分配。在整个内核程序运行周期中,全局存储器可以被GPU上的所有线程所共享)访问瓶颈:全局存储器访问瓶颈产生的原因是存在全局存储器访问延迟。内存和CPU之间几乎不存在访问延迟,而显存则位于显卡之外,使得访问全局存储器的代价非常高,达到GPU执行单元单个指令周期的几百倍。这里的全局存储器指的是一类存储单元,它们都位于显存上。原始数据从主机端内存传输到显存中供GPU处理器使用,访问全局存储器必不可少,如果大量的指令等待全局存储器访存,那么昂贵的访问延迟使得设备的计算能力大大降低;另一方面,对GPU显存的访问是以段(在设备计算能力为1.2的GPU设备上,段的长度为128Bytes)为基本单位的,同一时间对位于同一段内的多个访问都会被转化为对显存的一次访问(具体可参见本发明内容优化技术2全局存储器归并访问)。
2.共享存储器访问瓶颈:共享存储器访问瓶颈是因为共享存储器的存在访问冲突。共享存储器位于GPU处理器内部,主要用于线程之间通信和作为显存缓存。每个流多处理器(SM,Stream Multiprocessor)中的共享存储器被组织为大小相等的存储器模块,称为bank,每个bank的宽度固定为32/64bit,相邻的bank由16/32(计算能力2.0以上的bank宽度提升为63bit,bank控制器的数目提升到32个)个不同的存储器控制器来管理。由于每个bank控制器每个时钟仅能做一次存储访问,当多个线程访问的区域位于同一个bank时便会产生bank冲突(bank-conflict)。尽管共享存储器的访问延迟可以忽略不计,但bank-conflict访问冲突导致了共享存储器访问可能存在几个时钟周期的延迟。当遇到bank conflict时GPU分多周期完成该warp的访存,延迟的长度取决于bank conflict的严重程度,即如果32个线程都访问同一个bank,那么只有等待32个周期后,这条对共享存储器的访存操作才可以顺利完成。warp是GPU执行CUDA程序时基本的任务调度单位,目前CUDA的warp的大小为32个线程,处在同一个warp内的线程,以不同数据资源执行相同的指令,warp是一种SIMT执行模型(SIMT,Single Instruction Multiple Thread,是对SIMD,Single InstructionMultiple Data的一种改进)
3.指令执行依赖瓶颈:这里的指令流水线冲突主要指的是对寄存器数据的读写访问冲突(指令依赖冲突具体可参见文献张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.),当一条指令执行依赖于上一条或者临近指令的计算结果时,这条指令就会被流处理器延后,当这样的冲突频繁发生时,完整的处理器流水线会损失很多计算时间,从而降低程序的性能。
4.指令瓶颈:当程序大多时间处在执行指令流水线的状态时,GPU设备往往可以获得很高的指令吞吐量,流处理器的计算能力得到较为充分的利用,将这一类程序归为指令瓶颈。指令瓶颈是程序优化的较理想状态但这并不意味着程序的运行时间不能进一步减少。由于指令瓶颈要求指令流水线高负荷工作,只有当上述3中瓶颈都被解决时,指令瓶颈的优化才有意义。
优化技术
这里列举主要的优化技术(本领域技术人员能够明白在实际编程时的优化技术存在许多非常小的技巧,本发明在这里只列出公认的最有效技术,更多的技术细节可参见对应优化技术后的参考文献等),这些优化技术针对特定的性能瓶颈都可以实现有效的性能提升。
●全局存储器转共享存储器
对于频繁访问的全局存储器上的数据,将其拷贝到共享存储器,然后再从共享存储器上读取来使用,由于共享存储器的大小有限同时也需要作为线程通信的媒介,将访问最为频繁的显存数据转存在共享存储器里。(NVIDIA.CUDA C Programming Guide.January 2012.、Peng Wang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.、张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.)
●全局存储器访存归并
对于同一个warp内部的线程如果访问相同的段区域,访存请求可以在一次访存中完成。相反,跨越更多的区域段就需要更多次的全局存储器访问,使得访问代价提高,这就要求全局存储器的访问尽量归并。(NVIDIA.CUDA C Programming Guide.January 2012.、PengWang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.、张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.)
●解决共享存储器bank conflict
组织线程块(Thread block)(Thread block是GPU的任务分发与资源分配单位,同一个block内部的线程可以利用共享存储器实现通信,是线程间协作的主要对象)内部的warp使得共享存储器的访问分属于不同的bank,这要求程序编写者合理分配GPU线程任务。一个有效的手段是在定义共享存储器时,将一维的大小设为线程块宽度加一,这样在处理按行数据访问和按列数据访问时都不会引发bank conflict。(Peng Wang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.、张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.)
●共享存储器转存寄存器
对于频繁访问的共享存储器上的数据,将其拷贝到寄存器上,然后再从寄存器上读取来使用,使用寄存器充当共享存储器的的功能。这种方法主要解决共享存储器不够用或者共享存储器访问bank-conflict不可避免的情况。技术实现的难点在于合理的给每个线程分配寄存器和计算任务,使得寄存器充当共享存储器共享和缓存的作用,因为单个SM上寄存器数目有限,有时候为了让单个线程获得更多的寄存器,必须降低同一个SM上活跃warp的数目。(Peng Wang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.、张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.)
●提高线程级并行
提高一个SM上的active warp(active warp是指处在活动状态的warp,这一类的warp所需要的执行环境在硬件上均已准备好。由于硬件资源的限定,同一时间GPU上不可能为所有warp的线程提供执行环境(包括指令、寄存器、存储器等资源),active warp数目极大的影响线程执行的并行度)数目。线程级并行度是NIVIDA在CUDA架构提出来时极力提倡的并行方式。由于单个SM对在其上运行的线程块数目和资源占用有严格的限定,为了达到更多的active warp数目,需要控制好每个线程块的大小以及线程块使用的资源数目,综合SM上的设备资源上限从而达到更高的SM设备占有率(SM设备占有率又被成为占有率,是在单一SM上衡量active warp数目的指标),提高线程级并行度。SM的理论占有率由设备计算能力和线程块的资源分配决定,而实际取得的占有率也会受线程块数目和线程长度等因素影响。(具体可参考NVIDIA.CUDA C Programming Guide.January 2012.、Peng Wang.CUDAOptimization.In:NVIDIA GPU Technology Conference,2010.、张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.)
●提高指令级并行
指令级并行是在线程内部提高程序执行并行度的方法。由于CUDA设备支持小范围的指令乱序执行(可参考张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.),可以将一个线程内部循环执行部分自动或者手动的方式展开,通过添加新的临时变量来减少指令之间的数据相关性,从而为设备进行指令级并行提供支持。指令级并行度不能直观的反映在SM占有率上,但它可以更直接为SM提供足够的eligible warp(eligible warp是在单个指令周期内处于可以发射状态的线程warp,相较于active warp更直接的反映出设备计算单元的利用情况。eligible warp是顺利获取计算资源的那部分active warp,通常eligiblewarp的数目会小于active warp的数目),因此对于特定的CUDA设备可以显著提高指令的吞吐量。但由于GPU对指令乱序执行的支持仅限于局部指令,同时分支跳转语句会大大降低这种并行效率,因此提高指令级并行对提高程序并行度的作用也是有限的。(具体可参考V.Volkov.Better performance at lower occupancy.In:NVIDIA GPU Technology Conference,2010.和V.Volkov.Use registers and multiple outputs per thread on GPU,UC Berkeley,PMAA’10,June 30,2010)
●高吞吐量指令替换低吞吐量指令
对于可以实现相同功能的不同代码,优先选择指令吞吐量较大的指令,由于程序中任何指令的执行都需要特定的流水线周期,利用流水线周期较短的指令可以显著的提高指令吞吐量,从而在较短时间内完成功能。(可参考NVIDIA.CUDA C Programming Guide.January2012.、Peng Wang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.、张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.)
●减少指令分支
指令分支会造成处在同一个warp内部的线程分为两个甚至更多的warp分开执行,指令的执行数目得到倍数上的增长,同时也会破坏原有的指令缓存,增加指令获取的代价。因此尽可能将同一个操作的线程放在同一个warp中,保证程序中出现较少的分支,从而降低指令的数目,减少运行时间。(具体步骤可参考NVIDIA.CUDA C Programming Guide.January2012.、Peng Wang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.、张舒,褚艳利.GPU高性能计算之CUDA[M].中国水利水电出版社,2009.)
下面结合附图对本发明实施例进行详细的说明
如图1所示是CUDA并行架构的GPU程序优化方法针对不同瓶颈采用相应的优化方法,具体流程如下:
瓶颈判定方法
如图1所示,是CUDA程序的性能瓶颈判定是程序优化的关键步骤,在实际操作是必须要有明确的性能指标和判定标准,本发明使用Parrallel Nsight(NVIDIA公司发布的整合在Visual Studio中的CUDA程序调试与分析工具)工具获得某些GPU程序的性能指标,并采用分析和判定方法对GPU程序进行瓶颈判定,以下所使用到的性能指标都可通过ParrallelNsight工具测量得到。(Parrallel Nsight的使用方法参见NVIDIA.Parrallel Nsight UserGuide.2012.)
●全局存储器访问瓶颈的判定方法
全局存储器访问瓶颈的统一判定标准是SM需求占有率和SM实际占有率的比较。实际占有率可以通过CUDA程序分析工具中直接读出;需求占有率需要通过性能指标计算得出,这里给出一个实际可行计算公式:
需求占有率估计值ɑ=Na/48=(Nm/Ni)*T/48
其中Na为active warp数目,T为一次访存的延迟(T的具体数字范围从400到800不等),Nm/Ni为访存的请求次数与指令数目之比,Nm和Ni指标可以从Parrallel Nsight的CUDA Instruction Statistics和Memory Statistics结果中查出。这里需要说明的是,上述的计算方法仅是从整体上给指令执行和数据访问的比例做了粗略限定,即使需求占有率估计值小于实际占有率也不能完全保证指令执行时各个时段都不存在访问延迟等待。在实际优化过程中,上述公式计算的需求占有率应当尽量小于实际的占有率。
除了上述粗略的判定标准外,对于部分程序可以采用存储器访问替换的方式判定是否存在全局存储器访问瓶颈。具体做法是保留在全局存储器访问时使用的索引计算(不能因改变访问方式而缺失计算量),将对全局存储器的访问变为常数计算,如下所示
经过上述修改,程序中指令量并没有显著的改变,而全局存储器的访问量会大大缩减,这个时候我们观测程序的运行时间是否发生显著的变化,如果时间明显减少,那么可以断定原有的程序处在全局存储器访问瓶颈。需要注意的是,在这种方法中改变了局部变量的值,我们必须保证这些改变不会影响到之后程序的控制流,而仅仅是改变了数值结果。在最大限度不改变原有代码的基础上,通过改变全局存储器访问,观测程序执行时间发生的变化,从而得出程序是否存在全局存储器访问等待瓶颈。(具体可参考Peng Wang.CUDA Optimization.In:NVIDIA GPU Technology Conference,2010.)针对全局存储器访问瓶颈,有效的优化技术有:提高线程级并行度、提高指令级并行度、全局存储器转存共享存储器、全局存储器访存归并等。
●共享存储器访问瓶颈判定方法
共享存储器访问瓶颈的判断标准是共享存储器的冲突比例,程序中需要尽可能的减少或者避免bank conflict的发生。共享存储器内部的bank conflict可以通过Parrallel Nsight的CUDA Memory Statistics中得出发生共享存储器访问冲突的次数;与全局存储器访问瓶颈的方法类似,在不改变程序控制流的前提下修改共享存储器的访问方式,将对共享存储器的访问替换为指令计算,通过替换前后运行时间的对比也可以得出原有程序是否处在共享存储器访问瓶颈(具体参见性能瓶颈判定全局存储器访问瓶颈的判定方法)。
共享存储器的有效的优化技术是改进共享存储器的访问任务分配解决bank-conflict以及共享存储器转寄存器等。合理分配处在同一个warp内32个线程访问的共享存储器bank,最好以warp中线程的编号来分配共享存储器访问;对于不可避免会出现bank-conflict的共享存储器访问,如果没有线程通信的需要,可以考虑将共享存储器的数据放入寄存器来读取。
●流水线指令执行依赖瓶颈的判定方法
流水线是否存在大量的执行依赖可以从Parrallel Nsight等分析工具中得出的某些性能参数,并进行综合分析和判断得到。具体方法如下:Parrallel Nsight profile分析工具的Issue Stalls Tab反映了影响指令发射的各种因素在程序中的比例,观察Warp IssueEfficiency饼状图,如果eligible warp的数目在较多的时钟周期里都小于2个,那么说明指令的发射收到了拖延,观察Issue Stall Reasons饼状图,如果Execution Dependency所占的比例最大,那么就说明程序存在大量的指令执行依赖。这里需要注意的是,从ParrallelNsight分析工具中观测到Execution Dependency严重的程序也可能存在全局存储器或者共享存储器访问瓶颈,因此,需要先利用全局存储器或者共享存储器访问瓶颈的判定标准排除存储器访问瓶颈的可能,才能最终确定程序处在指令执行依赖瓶颈。
在前两种存储器访问瓶颈优化的较为充分时,可以对优化程序中出现的指令执行依赖瓶颈进行处理,进一步提高程序性能。指令执行依赖瓶颈的优化技术有提高线程级并行度和提高指令级并行度等。
●指令瓶颈的判定方法
IPC(Instructions Per Cycle的缩写)反映了GPU设备的指令吞吐量。理论IPC受限于设备的计算能力,而实际的IPC可以通过Parrallel Nsight等分析工具中得出,反映了GPU程序运行时指令的吞吐量。在GPU体系结构中,不同的指令在单位时间内具有不同的指令吞吐量,设备理论的IPC(设备理论IPC上限是假设所有执行的指令均为最大吞吐量指令的IPC值)是按照最大吞吐量的标准计算的,实际执行的指令类型不一定是最大吞吐量;另一方面,延迟等待和冲突等原因也同样制约着实际IPC。由于以上原因,实际的IPC很难达到理论IPC极限。
指令瓶颈的判定标准是当前程序的IPC是否达到或者接近指令瓶颈的IPC并非理论IPC极限。在不同的CUDA设备计算能力中理论的IPC极限分别是1.0(计算能力1.x),2.0(计算能力2.0)和4.0(计算能力2.1),通常情况下,实际取得的IPC分别达到0.8(计算能力1.x),1.7(计算能力2.0)和2.3(计算能力2.1)就已经接近设备的计算能力(参考),可以作为指令瓶颈的粗略判定指标。
对于指令瓶颈的优化方法有使用大吞吐量指令替换小吞吐量指令、减少代码中分支部分等。
如图2所示,本发明设计了具体的GPU程序优化流程和步骤。按照瓶颈的优先级依次判断需要调优的程序是否处于性能瓶颈,并选择适合的优化技巧对性能瓶颈进行优化,使得程序的性能不断提高。
综合上述瓶颈判定以及相应的优化方法确定优化流程以及具体的优化步骤。以下每一步优化步骤分别针对上述的四种性能瓶颈,按照优先级依次解决。对于每一种瓶颈本发明列出多个优化技术可供使用,并附有使用条件的说明。每一步的优化可能执行多次,因为任何优化可能仅仅只是改善了某种性能瓶颈,并没有彻底解决该性能瓶颈,需要不断优化直至程序从一种性能瓶颈状态转化为另一种状态。
为了更加清晰的说明各种优化技术的使用,本发明以矩阵乘法的优化为例(两个n*n的矩阵相乘得到n*n的结果矩阵)具体说明实际的优化操作。
●Step1:
针对已有的GPU程序,首先计算程序需求占有率。将需求占有率与实际占有率进行比较,若实际占有率不能满足需求占有率,那么选取合适的全局存储器访问优化技术即高线程级并行度、提高指令级并行度、全局存储器转存共享存储器、全局存储器访存归并,来解决全局存储器访问延迟瓶颈。重复本步骤直至实际占有率大于或远大于需求占有率。具体操作如下:
如何选取合适的优化技术取决于存储器访问的特点,这些工作要求程序编写者熟悉算法的实现和设备的硬件特性:如果读取的数据在之后程序中被多次访问并且数据量不是很大时,这部分数据适合先放在共享存储器中,再对共享存储器进行访问;如果每个线程完成类似或者同样的功能,可以将访问的数据在显存上连续存储,分配线程任务使得相邻的线程处理相邻的存储器单元,从而满足归并访问;如果编写代码时已明确访存的数目和执行的操作时,让每个线程处理更多彼此无关的任务,减少指令之间的数据冲突,为指令集并行提供条件;在不影响程序实现功能的前提下,合理分配每个SM上的寄存器、共享存储器等资源,提高SM的占有率。
在矩阵乘法的CUDA实现中,首先遇到的问题就是全局存储器访问瓶颈(输入矩阵事先放在全局存储器中),矩阵乘法要求以n3的复杂度计算结果矩阵,两个输入矩阵的每一个元素会被访问n次,当n特别大时,全局存储器访问开销巨大,考虑到每个元素的访问重复性,我们将全局存储器转存在共享存储器,同时转存的过程中尽量让访问满足归并访问。为了达到足够的SM占有率,我们建立多个线程块,每个线程块完成结果矩阵中一块内容的计算。考虑256*256的矩阵乘法,我们设计block维度为16*16,每个block完成结果矩阵中16*16的大小,共需要16*16个block。每个block的共享存储器大小为16*16*单个数据宽度。
●Step2:
针对Step1优化后不存在全局存储器访问瓶颈的GPU程序,查看共享存储器bank-conflicts的数目,判断是否存在共享存储器访问等待并对其进行优化,重复本步骤直至程序不存在全局存储器访问和共享存储器访问瓶颈。具体操作如下:
如果存在共享存储器bank-conflict,优先解决bank-conflict,如果每个线程处理彼此无关任务,可以将访问不同bank的线程放在同一个warp内;当不可避免的需要访问同一个bank内部的数据时,考虑这部分数据的大小以及需要在线程间通信等因素,将这部分共享存储器的数据转存在寄存器中,可以考虑减少SM上线程的数目来获取额外的寄存器资源。
在矩阵乘法的下一步优化中,为了保证共享存储器访问不存在bank-conflict,将共享存储器的维度定义为warp数目加一,并严格按照线程所在warp中的ID来访问共享存储器。在上述工作之后我们仍然看到程序存在较多的bank-conflict,此时考虑将共享存储器转存寄存器,将一个block中线程的数目缩小,利用较少的线程完成之前更多线程的任务,使用寄存器充当原先共享存储器的作用。重新设计block维度为16*4,共享存储器仍然为16*16,每个线程额外开辟16个寄存器充当共享存储器,同时,每个线程完成之前16个线程的任务。
●Step3:
针对Step2优化后不存在存储器访问瓶颈的GPU程序,考察程序中是否存在流水线指令依赖瓶颈,如果存在依赖冲突,解决指令依赖,重复本步骤直至程序的实际IPC达到或者接近指令瓶颈IPC。具体操作如下:
为了解决指令流水线依赖冲突,需要针对程序特点选择线程级并行或者指令级并行:当GPU中存在复杂的逻辑控制,每个线程的任务不尽相同,或者存在大量不可预测的分支跳转时,可以考虑增大SM的占有率,利用更多的线程级并行来掩盖指令流水线延迟;当GPU程序出现重复大量无关的相同工作如对存储器访问时,考虑将多个无关的任务分配给单独的线程来处理,利用更多的指令级并行解决依赖冲突。这里需要指出的是在CUDA架构的较高版本对解决指令依赖冲突的要求不同(计算能力1.x的设备需要所有的SM尽可能达到1个eligiblewarp,计算能力2.0的设备需要达到2个eligible warp,而计算能2.1的设备则需求2个以上的eligible warp)。这对使用指令级并行来优化指令流水线延迟提出了更高的要求。
在矩阵乘法的下一步优化中,由于每个线程处理更多的任务,而这些任务之间是不存在数据相关性的,将它们连续发射可以提高指令并行度。这里需要注意的是,每条语句应当尽量小,如几个乘法或者加减法。当执行任务过大时,会因指令缓存不足,造成乱序发射失效,使得指令并行失去意义。单个语句缩小到一次乘法和一次加法,连续执行互不冲突的16次。
Step4:
在上述3步的优化工作后可以得到具有较高实际IPC的程序,下一步考虑使用指令瓶颈的优化方法对程序进一步优化。具体操作如下:
如果程序中存在影响warp分支的分支跳转,优先将这部分工作移到同一个warp或者相邻的线程中;针对部分程序,某些功能的实现存在更优指令可以替代原有指令(如在精度允许的条件下,将双精度替换为单精度等),使用大吞吐量指令代替小吞吐量指令实现相同功能。
在已有较高IPC的矩阵乘法实现中,为了进一步提高程序的性能,考虑减少分支跳转语句,将原先的for循环手动展开,同时将多次使用局部变量存储在寄存器中,利用上述手段进一步提高程序性能。这里添加新的临时指针,将寄存器和共享存储器的二维访问转为一维访问,使得连续16个数据的访问计算量减少。
Claims (9)
1.一种基于CUDA并行环境的GPU程序优化方法,其步骤包括:
1)根据CUDA上的程序分析工具对GPU程序进行检测,得到程序需求占有率并判断此时程序是否存在全局存储器访问瓶颈,同时对所述全局存储器访问瓶颈进行消除,进入步骤2);
2)根据共享存储器中bank-conflicts访问冲突的数目判断所述步骤1)的GPU程序中是否存在共享存储器访问瓶颈,同时消除所述共享存储器访问瓶颈和新生成的全局存储器访问瓶颈,进入步骤3);其中,所述全局存储器访问瓶颈判断方法是:若实际占有率不能满足需求占有率,则GPU程序中存在全局存储器访问瓶颈,所述实际占有率通过CUDA程序分析工具中Parrallel Nsight的CUDA Memory Statistics和Instruction Statistics读出;所述共享存储器中bank-conflicts访问冲突的数目通过Parrallel Nsight的CUDA Memory Statistics中得出;
3)使用CUDA的程序分析工具在所述步骤2)的GPU程序提取出性能参数,判断是否存在流水线指令执行依赖瓶颈并消除该流水线指令的冲突,得到实际IPC达到指令瓶颈的IPC的GPU程序进入步骤4);其中IPC表示Instuction Per Cycle,用以反映GPU设备的指令吞吐量;4)在所述步骤3)中若GPU程序实际IPC达到指令瓶颈的IPC,则进行指令瓶颈优化处理;
5)重复遍历以上步骤1)—4),直至所述GPU程序不存在上述步骤1)-4)中的任意一项瓶颈,完成GPU程序优化。
2.如权利要求1所述的基于CUDA并行环境的GPU程序优化方法,其特征在于,所述程序需求占有率α=Na/48=(Nm/Ni)*T/48,其中Na为active warp数目,T为一次访问存储延迟,Nm/Ni为访问存储请求次数与指令数目之比。
3.如权利要求1所述的基于CUDA并行环境的GPU程序优化方法,其特征在于,所述步骤1)重复直至实际占有率大于需求占有率,消除所述步骤1)中全局存储器访问瓶颈的优化方法包括:提高线程级并行度、提高指令级并行度、全局存储器转存共享存储器、全局存储器访存归并。
4.如权利要求1所述的基于CUDA并行环境的GPU程序优化方法,其特征在于,所述步骤2)中共享存储器访问瓶颈消除方法为:改进共享存储器的访问任务分配解决bank-conflicts访问冲突和/或共享存储器转寄存器。
5.如权利要求1所述的基于CUDA并行环境的GPU程序优化方法,其特征在于,所述流水线指令执行依赖瓶颈的优化处理方法为提高线程级并行度和/或提高指令级并行度;
当GPU中存在复杂的逻辑控制,每个线程的任务不尽相同,或者存在大量不可预测的分支跳转时,则通过增大SM的占有率,利用更多的线程级并行来掩盖指令流水线延迟,其中SM为Stream Multiprocessor缩写,用以表示流多处理器;
当GPU程序出现重复大量无关的相同工作时,则通过将多个无关的任务分配给单独的线程来处理的方法解决依赖冲突。
6.如权利要求1所述的基于CUDA并行环境的GPU程序优化方法,其特征在于,所述指令瓶颈优化处理为:如果程序中存在影响warp分支的分支跳转,优先将这部分工作移到同一个warp或者相邻的线程中,或者高吞吐量指令替换低吞吐量指令和/或减少指令分支。
7.如权利要求1所述的基于CUDA并行环境的GPU程序优化方法,其特征在于,所述步骤3)中流水线指令执行依赖瓶颈从GPU程序中Parrallel Nsight分析工具的Issue Stalls Tab得到,基于Warp Issue Efficiency饼状图中eligible warp的数目和/或Issue Stall Reasons饼状图中Execution Dependency所占的比例。
8.如权利要求1所述的基于CUDA并行环境的GPU程序优化方法,其特征在于,对部分程序所述全局存储器访问瓶颈的判断方法采用存储器访问替换的方法:保留在全局存储器访问时使用的索引计算,通过改变全局存储器访问,观测程序执行时间发生的变化。
9.如权利要求4所述的基于CUDA并行环境的GPU程序优化方法,其特征在于,所述改进共享存储器的访问任务时将共享存储器的维度定义为warp数目加一,并按照线程所在warp中的ID来访问共享存储器。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210444220.4A CN102981807B (zh) | 2012-11-08 | 2012-11-08 | 一种基于cuda并行环境的gpu程序优化方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210444220.4A CN102981807B (zh) | 2012-11-08 | 2012-11-08 | 一种基于cuda并行环境的gpu程序优化方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN102981807A CN102981807A (zh) | 2013-03-20 |
CN102981807B true CN102981807B (zh) | 2015-06-24 |
Family
ID=47855878
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201210444220.4A Active CN102981807B (zh) | 2012-11-08 | 2012-11-08 | 一种基于cuda并行环境的gpu程序优化方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN102981807B (zh) |
Families Citing this family (16)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103955394B (zh) * | 2014-04-03 | 2017-05-17 | 北京大学 | 一种基于推迟提交的gpu虚拟化优化方法 |
CN105045564A (zh) * | 2015-06-26 | 2015-11-11 | 季锦诚 | 图形处理器中的前端动态共享方法 |
CN105487915B (zh) * | 2015-11-24 | 2018-11-27 | 上海君是信息科技有限公司 | 一种基于延迟发送机制的gpu虚拟化性能提升的方法 |
CN106648545A (zh) * | 2016-01-18 | 2017-05-10 | 天津大学 | 一种gpu中用于分支处理的寄存器文件结构 |
CN106648546A (zh) * | 2016-09-07 | 2017-05-10 | 北京大学 | 用于gpu寄存器分配和并行度管理的协同优化编译方法 |
CN108009008B (zh) * | 2016-10-28 | 2022-08-09 | 北京市商汤科技开发有限公司 | 数据处理方法和系统、电子设备 |
CN108564164B (zh) * | 2018-01-08 | 2022-04-29 | 中山大学 | 一种基于spark平台的并行化深度学习方法 |
CN108874518B (zh) * | 2018-05-21 | 2021-05-11 | 福建省数字福建云计算运营有限公司 | 一种任务调度方法及终端 |
CN109189478B (zh) * | 2018-08-27 | 2020-12-29 | 中国科学院计算技术研究所 | 针对应用程序的反馈优化方法 |
CN109800088B (zh) * | 2018-11-14 | 2023-06-20 | 西安翔腾微电子科技有限公司 | 基于训练的gpu配置管理方法、装置、存储介质和gpu |
CN109634830B (zh) * | 2018-12-19 | 2022-06-07 | 哈尔滨工业大学 | 一种基于多特征耦合的cuda程序一体化性能预测方法 |
CN110457238B (zh) * | 2019-07-04 | 2023-01-03 | 中国民航大学 | 减缓GPU访存请求及指令访问cache时停顿的方法 |
CN111552478B (zh) * | 2020-04-30 | 2024-03-22 | 上海商汤智能科技有限公司 | 用于生成cuda程序的设备、方法和存储介质 |
CN111694648B (zh) * | 2020-06-09 | 2023-08-15 | 阿波罗智能技术(北京)有限公司 | 一种任务调度方法、装置以及电子设备 |
CN111857831B (zh) * | 2020-06-11 | 2021-07-20 | 成都海光微电子技术有限公司 | 一种存储体冲突优化方法、并行处理器及电子设备 |
CN111767305B (zh) * | 2020-06-23 | 2023-04-07 | 电子科技大学 | 一种自适应的数据库混合查询方法 |
Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101957743B (zh) * | 2010-10-12 | 2012-08-29 | 中国电子科技集团公司第三十八研究所 | 并行数字信号处理器 |
Family Cites Families (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
GB2483903A (en) * | 2010-09-24 | 2012-03-28 | Advanced Risc Mach Ltd | Instruction which specifies the type of the next instruction to be executed |
-
2012
- 2012-11-08 CN CN201210444220.4A patent/CN102981807B/zh active Active
Patent Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101957743B (zh) * | 2010-10-12 | 2012-08-29 | 中国电子科技集团公司第三十八研究所 | 并行数字信号处理器 |
Non-Patent Citations (1)
Title |
---|
基于矩量法计算粗糙面电磁散射的GPU加速方法研究;付彦明;《万方学术期刊数据库》;20120731;第25-30页 * |
Also Published As
Publication number | Publication date |
---|---|
CN102981807A (zh) | 2013-03-20 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN102981807B (zh) | 一种基于cuda并行环境的gpu程序优化方法 | |
Ausavarungnirun et al. | Exploiting inter-warp heterogeneity to improve GPGPU performance | |
Fang et al. | swdnn: A library for accelerating deep learning applications on sunway taihulight | |
CN104081315B (zh) | 包括线程合并的用于能效和节能的方法、装置和系统 | |
Sethia et al. | Mascar: Speeding up GPU warps by reducing memory pitstops | |
CN102902512B (zh) | 一种基于多线程编程及消息队列的多线程并行处理方法 | |
US10949200B2 (en) | Methods and apparatus for executing data-dependent threads in parallel | |
CN105468439B (zh) | 在cpu-gpu异构框架下遍历固定半径内邻居的自适应并行方法 | |
US20100299671A1 (en) | Virtualized thread scheduling for hardware thread optimization | |
CN103246542B (zh) | 智能缓存及智能终端 | |
Abdolrashidi et al. | Wireframe: Supporting data-dependent parallelism through dependency graph execution in gpus | |
US20140068581A1 (en) | Optimized division of work among processors in a heterogeneous processing system | |
CN108595258A (zh) | 一种gpgpu寄存器文件动态扩展方法 | |
Chen et al. | Guided region-based GPU scheduling: utilizing multi-thread parallelism to hide memory latency | |
Aananthakrishnan et al. | PIUMA: programmable integrated unified memory architecture | |
Chen et al. | Balancing scalar and vector execution on gpu architectures | |
Li et al. | Efficient kernel management on GPUs | |
Falahati et al. | Power-efficient prefetching on GPGPUs | |
CN105653243A (zh) | 一种通用图形处理器多任务并发执行的任务派发方法 | |
Falahati et al. | ISP: Using idle SMs in hardware-based prefetching | |
Zhang et al. | Buddy SM: sharing pipeline front-end for improved energy efficiency in GPGPUs | |
Uddin et al. | Signature-based high-level simulation of microthreaded many-core architectures | |
Siddiqui et al. | Design Space Exploration of Embedded Applications on Heterogeneous CPU-GPU Platforms | |
Weng et al. | Raise: Efficient gpu resource management via hybrid scheduling | |
Zhang et al. | Dynamic front-end sharing in graphics processing units |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant | ||
TR01 | Transfer of patent right |
Effective date of registration: 20200721 Address after: 830-3, 8 / F, No. 8, Sijiqing Road, Haidian District, Beijing 100195 Patentee after: Beijing weishiwei Information Technology Co.,Ltd. Address before: 100871 Haidian District the Summer Palace Road,, No. 5, Peking University Patentee before: Peking University |
|
TR01 | Transfer of patent right |