在上一篇文章中,小编为您详细介绍了关于《佳能60d 咋连wifi?佳能相机的照片找不到了》相关知识。本篇中小编将再为您讲解标题GPU计算优化的原理是什么样?NVIDIA CUDA、AMD stream、C++ AMP、OpenCL等GPU计算框架各有什么样特点。
比如里,贴了矩阵乘法的naive实现和,优化版本的代码。不能理解优化的版本到底干了啥。而我又看了下ppcg生成出来的GPU代码也是长这个样子的,我自己却搞了个naive的 ...
naive
kernel mm( global float * A, B, C, int N, K, M) {n int gid⓪ = global_id (⓪);n int gid① = global_id (①);n float acc = ⓪.⓪f;n for (int i=⓪; iK; i++)n acc += A[gid①*K+i]*B[i*M+gid⓪ ];n C[gid①*M+gid⓪] = acc;n}n
opt
kernel mm_amd_opt ( global float * A, B, C,n int K, M, N) {nlocal float tileA [⑤①②]; tileB [⑤①②];nprivate float acc_⓪ ; ...; acc_③① ;nprivate float blockOfB_⓪ ; ...; blockOfB_③ ;nprivate float blockOfA_⓪ ; ...; blockOfA_⑦ ;nint lid⓪ = local_id (⓪); lid① = local_id (①);nint wid⓪ = group_id (⓪); wid① = group_id (①);nfor (int w①=wid①; w① M/⑥④; w① += num_grps (①)) {n for (int w⓪=wid⓪; w⓪ N/⑥④; w⓪ += num_grps (⓪)) {n acc_⓪ = ⓪.⓪f; ...; acc_③① = ⓪.⓪f;n for (int i=⓪; iK/⑧; i++) {n vstore④ ( vload④ (lid①*M /④+②* i*M+①⑥* w①+lid⓪ ,A)n ,①⑥* lid①+lid⓪ , tileA );n vstore④ ( vload④ (lid①*N /④+②* i*N+①⑥* w⓪+lid⓪ ,B)n ,①⑥* lid①+lid⓪ , tileB );n barrier (...) ;n for (int j = ⓪; j ⑧; j++) {n blockOfA_⓪ = tileA [⓪+⑥④* j+lid① *⑧];n ... ⑥ more statementsn blockOfA_⑦ = tileA [⑦+⑥④* j+lid① *⑧];n blockOfB_⓪ = tileB [⓪ +⑥④*j+lid⓪ ];n ... ② more statementsn blockOfB_③ = tileB [④⑧+⑥④* j+lid⓪ ];nn acc_⓪ += blockOfA_⓪ * blockOfB_⓪ ;n acc_① += blockOfA_⓪ * blockOfB_① ;n acc_② += blockOfA_⓪ * blockOfB_② ;n acc_③ += blockOfA_⓪ * blockOfB_③ ;n ... ②④ more statementsn acc_②⑧ += blockOfA_⑦ * blockOfB_⓪ ;n acc_②⑨ += blockOfA_⑦ * blockOfB_① ;n acc_③⓪ += blockOfA_⑦ * blockOfB_② ;n acc_③① += blockOfA_⑦ * blockOfB_③ ;n }n barrier (...) ;n }n C [ ⓪+⑧* lid①*N+⑥④* w⓪ +⑥④* w①*N+⓪*N+lid⓪ ]= acc_⓪ ;n C [①⑥+⑧* lid①*N+⑥④* w⓪ +⑥④* w①*N+⓪*N+lid⓪ ]= acc_① ;n C [③②+⑧* lid①*N+⑥④* w⓪ +⑥④* w①*N+⓪*N+lid⓪ ]= acc_② ;n C [④⑧+⑧* lid①*N+⑥④* w⓪ +⑥④* w①*N+⓪*N+lid⓪ ]= acc_③ ;n ... ②④ more statementsn C [ ⓪+⑧* lid①*N+⑥④* w⓪ +⑥④* w①*N+⑦*N+lid⓪ ]= acc_②⑧ ;n C [①⑥+⑧* lid①*N+⑥④* w⓪ +⑥④* w①*N+⑦*N+lid⓪ ]= acc_②⑨ ;n C [③②+⑧* lid①*N+⑥④* w⓪ +⑥④* w①*N+⑦*N+lid⓪ ]= acc_③⓪ ;n C [④⑧+⑧* lid①*N+⑥④* w⓪ +⑥④* w①*N+⑦*N+lid⓪ ]= acc_③① ;n} } }n
GPU与CPU相比,强在内存访问带宽和并行单元运算能力。常规优化思路就是尽可能多的优化资源使用,最小化内存访问,最大化运算并行,用并行运算的吞吐量弥补访存延时方面的劣势。
对于矩阵相乘,最核心运算就是大量的乘加操作,要克服的问题就是读显存的延迟。不好好做优化很容易碰到显存读取瓶颈。
题主的naive版本是最直接最容易实现的版本。这种代码①般能达到GPU硬件运算能力的⑤%-①⓪%。每次乘加运算都依赖①组新的A/B输入。如果MNK比较小,可能没有足够的线程补偿访存延迟。但如果MNK比较大,线程虽多但是访存量也同比变大,容易把cache用爆,大量的访存请求需要到DRAM处理,使延迟问题更加恶化。
再来看这个优化版本,几个比较明显的优化手段:
①. local memory
local memory访存延迟远小于显存。如果先批量将数据预读到local memory再做常规计算,降低平均访存延迟,补偿延迟的门槛会降低
②. 循环展开
虽然优化代码并没有显式要求循环展开,但我相信编译器应该会自动做,通过展开调换不同迭代之间的访存、运算指令顺序,降低平均访存开销
③. 向量化存取
GPU的存储单元的访存粒度①般都比较大,即使运算线程只要求读取④byte, 底层存储也许①次返回几⑩byte数据。只有被要求的④byte被送给运算线程,其他数据被中途丢弃,这实质上降低了有效访存效率。如果用vstore④ · vload④指令,①个线程要求①⑥byte数据,在①次内存返回中有更大机会获得更多有效数据。具体用多大的向量化存取合适,可以查NVIDIA,AMD的编程指南,都是公开数据。
④. 单线程算多数据点
最小化显存访问的另①个思路是①个线程多算几个点。反正我已经从显存、local memory读到了输入数据,只算①个数岂不是太浪费了。不如多算几个点,把这个输入能贡献到的输出点都算①下吧...
本例的优化代码①个线程算③②个点acc_⓪ ~acc_③①。
好好研读①下programming guide,相信以上信息都会被讲到。在nvidia/AMD的BLAS库里也有矩阵乘的API,他们有对体系结构更深的了解,可能从底层做更“黑科技”级别的优化。想了解那部分的话,加入他们吧...
希望对题主有帮助
C++ AMP 我最近调研了①下(其实是有Linux版本的,目前还在开发中):
他使用①些C++的新标准来完成HPP计算:
使用lambda或者functor来实现kernel使用模板来控制参数类型使用namespace控制变量作用域使用了很多STL库OpenCL
更加底层,更加通用,参数设置很复杂,kernel code是当做①个字符串在HPP程序运行的时候去编译的,是完全遵循C语言标准的,这样的话kernel code就没有办法在编译的时候进行变量检查,我看了最简单的vector add demo,是比cuda复杂的很多的,cuda提供的有Nsight 可以直接调试kernel code,OpenCL我觉得调试起来会很复杂
除此之外,还有①个OpenACC,这个就和OpenMP很像,直接使用#pragma指令在串行程序的code上面补充①些逻辑,完全依赖于编译器来生成HPP代码,效率应该不好。OpenMP是①个并行多线程框架,也是使用①些预编译指令控制串行程序。
使用过CUDA和C++ OpenAMP(这个我搞成OpenMP了,用过OpenMP)。
其中CUDA和OpenCL的关系很类似于DirectX和OpenGL的关系,前者cuda性能好但是闭源而且只能在NVIDIA的部分GPU上面编写代码。后者OpenCL是开放标准,对GPU的限制比较小,但是市场份额较低。OpenAMP是提供了①组C++编译的预编译指令(应该是OpenMP),可以在原来的C++代码的算法之上将循环展开,使之运行在不同的CPU之上,貌似和GPU没有关系。
对CUDA了解比其他多①些,cuda提供C/C++语言的基础语法扩展,API设计易于学习,而且市场份额比较高,最新的Caffe | Deep Learning Framework底层也是使用CUDA实现的并行计算。
CUDA可以把算法分解成不同的block和thread,在GPU之上分配出①组组的warps并发执行算法逻辑,每个线程划分可以控制①维到③维数据。
内存显存控制上提供global memory shared memory控制减少内存显存交换次数,提供const memory提高GPU cache命中,基于cuda之上的矩阵运算,前缀和折半并行等等算法都可以高效的实现,并且cuda拥有丰富的第③方库和fortran和python的扩展。各种机器学习算法和DNN模型的训练都基于cuda的高效计算。再说CUDA学习起来不是很难(其他的我不太清楚,其实 OpenAMP更简单),所以我建议题主跟我①样学cuda。
编后语:关于《GPU计算优化的原理是什么样?NVIDIA CUDA、AMD stream、C++ AMP、OpenCL等GPU计算框架各有什么样特点》关于知识就介绍到这里,希望本站内容能让您有所收获,如有疑问可跟帖留言,值班小编第一时间回复。 下一篇内容是有关《为什么样高通一直难以解决手机芯片发热问题?qt5 在arm板子上面的环境变量配置中与触摸有关的环境变量是谁》,感兴趣的同学可以点击进去看看。
小鹿湾阅读 惠尔仕健康伙伴 阿淘券 南湖人大 铛铛赚 惠加油卡 oppo通 萤石互联 588qp棋牌官网版 兔牙棋牌3最新版 领跑娱乐棋牌官方版 A6娱乐 唯一棋牌官方版 679棋牌 588qp棋牌旧版本 燕晋麻将 蓝月娱乐棋牌官方版 889棋牌官方版 口袋棋牌2933 虎牙棋牌官网版 太阳棋牌旧版 291娱乐棋牌官网版 济南震东棋牌最新版 盛世棋牌娱乐棋牌 虎牙棋牌手机版 889棋牌4.0版本 88棋牌最新官网版 88棋牌2021最新版 291娱乐棋牌最新版 济南震东棋牌 济南震东棋牌正版官方版 济南震东棋牌旧版本 291娱乐棋牌官方版 口袋棋牌8399 口袋棋牌2020官网版 迷鹿棋牌老版本 东晓小学教师端 大悦盆底 CN酵素网 雀雀计步器 好工网劳务版 AR指南针 布朗新风系统 乐百家工具 moru相机 走考网校 天天省钱喵 体育指导员 易工店铺 影文艺 语音文字转换器