Skip to content

【PFCC-Roadmap】算子性能优化 #42286

Open
@luotao1

Description

@luotao1

Roadmap

OP性能是飞桨框架重要功能之一,通过 OP benchmark,我们发现有些OP性能不够好,没有充分利用硬件算力。石墨表格《PFCC-Roadmap》之【飞桨 OP 性能优化】为当前在Paddle中部分性能需要优化的案例,我们内部在不断地进行优化。你如果对这方面有兴趣,欢迎参加此项活动。

目前主要以CUDA编程为主,若对手写Kernel的概念了解不多,请详细阅读CUDA 编程模型概述。我们通常使用以下方法对GPU算子进行性能优化:

  1. 数据向量化读写:GPU kernel 的性能瓶颈常被划分为计算瓶颈compute-bound和访存瓶颈memory-bound,当前硬件架构不断更新,算力不断提高,算力与带宽的差距越来越大,导致越来越多的 kernel 性能受制于访存瓶颈。用户可采用常见的int4,float4等向量化类型实现数据的向量化读写操作,详见CUDA相关文档。当然,鼓励采用通用化的数据类型表示方法 AlignedVector ,以适应不同的向量化读写规则,具体使用案例见gelu_funcs.h.

  2. 快速计算方法:针对前面提到的计算瓶颈问题,我们提供一些基础的优化策略供参考:

    • 快速整型除法:GPU kernel中难免需要计算线程的索引 (index) 进而完成计算,部分索引计算时可能涉及除法,若出现连续除法或取模计算,如int index = a/b/c ,计算性能难免受到影响。出现此类时,推荐采用FastDivmod 方法完成计算索引计算,使用方法详见pooling.cu.
    • warp计算加速工具 :CUDA内置了一套warp级别的shuffle操作指令,能够提升计算效率。Paddle基于此提供了一套可加速Warp级和block级运算的指令库math_cuda_utils.h,可加速warp内或block内的最大值、最小值、求和等操作.
    • 内置intrinsic:CUDA内部提供了多种intrinsic计算方法,如针对float16类型的向量级计算__hadd2(详见CUDA相关文档),灵活运用这类计算可以解决这类case的性能不足问题。除此之外,建议谨慎使用_expf,_fdivideintrinsic,这类计算通过牺牲精度以提升性能,但是Paddle作为核心训练框架,OP精度对最终的模型收敛性会有影响.
    • 循环展开:采用#pragma unroll指令,编译器会展开具有已知循环次数的小循环加速循环的执行效率.
  3. 合理的线程配置策略:GPU Kernel通常需要设置线程配置参数,以确定执行kernel时可分配的计算资源,选择合理的配置参数,能够优化计算Kernel的性能,影响线程配置的因素主要有以下几个方面:

    • 为了将bank冲突将到最低,应尽量使每个block含有的线程数是64的倍数;
    • block的数量是应当是流处理器(SM) 的2倍以上,避免当某个block中线程被同步时,对应的硬件SM闲置;
    • block中的线程数应该设置成Warp尺寸的整数倍,且不超过最大线程数的规定。 一个block中设置的线程过多会导致每个线程可利用的寄存器变少,单寄存器变少时因访问溢出寄存器数据(溢出的数据在设备存储器中)致计算变慢,甚至调用失败。

    推荐采用gpu_launch_config.h中的线程配置方法选择较为合理的配置参数,若有更好的线程设置策略,欢迎补充。

  4. 高性能计算库:飞桨内置了一套模块化的高性能计算组件库kps,可以模块化、高性能地完成GPU Kernel实现及优化。此外,若采用如cublas等高性能计算库能获得显著的性能收益,也欢迎使用,cublas库使用示例见matmul_kernel_impl.h, cudnn库的使用示例见conv_kernel.cuthrust库使用示例见coalesced_kernel.cu.

Metadata

Metadata

Assignees

No one assigned

    Labels

    PFCCPaddle Framework Contributor Club,https://github.com/PaddlePaddle/community/tree/master/pfcc

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions