CUDA 学习(十七)优化策略2:内存因素

Posted tiemaxiaosu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CUDA 学习(十七)优化策略2:内存因素相关的知识,希望对你有一定的参考价值。

一、内存带宽

       内存带宽和延迟是所有应用程序都要考虑的关键因素,尤其是GPU应用程序。带宽是指与某个给定目标之间传输的数据量。在GPU的情况下,我们主要关心的是全局内存带宽。延迟则是操作完成所用的时间。

       GPU上的内存延迟设计为由运行在其他线程束中的线程所隐藏。当线程束访问的内存位置不可用时,硬件向内存提交一次读或者写请求。如果同一线程束上其他线程访问的是相邻内存位置并且内存区域的开始位置是对齐的,那么该请求会自动与这些线程的请求组合或者合并。如果线程没有访问连续的内存地址,会导致内存带宽快速地下降。例如,如果线程0 读取地址0、1、2、3、...、31,线程1 读取32、33、34、...、63 地址,它们将不会被合并。实际上,每个线程,硬件会提交一个至少32字节的请求。未被使用的字节将从内存中取出并直接丢弃。因此,如果不仔细考虑内存是如何被使用的,你就只能获得设备上实际可用带宽的很小一部分。


二、限制的来源

       内核通常被两个关键因素限制:内存延迟/ 带宽 和 指令延迟/ 带宽。当某一个是关键的限制因素,却对另一个进行优化时,会花费大量的精力并且只会得到很少的回报。因此,理解这两类关键因素中哪个正在限制系统的性能,对于指导你合理的分配精力很关键的。


三、内存组织

       在许多GPU应用程序中,使用正确的内存模式往往是关键的考虑因素。CPU 程序通常在内存中以行的方式安排数据。必须尝试安排内存模式以使连续线程对内存的访问以列的方式进行。此原则同时适用于全局内存和共享内存。这意味着对于给定的线程束(32个线程),线程0应该访问偏移量为0的地址,线程1访问偏移量为1的地址,线程2访问偏移量为2的地址,以此类推。


四、内存访问以计算比率

        内存操作与计算操作的比率是值得思考的问题。我们期望的理想比例至少是10:1。也就是说,对于每个内核,从全局内存执行的读取操作需要执行10条或更多的指令。这些指令可能是数组索引计算、循环计算、分支或条件判断。每个指令都应该对有效地输出起到一定的贡献。特别是循序没有展开时,它经常会增加开销但并不会有助于任何有用的工作。


五、循环融合和内核融合

       循环融合是指两个明显独立的循环在一段范围内交错地执行。例如,循环1 从0 执行到100,循环2 从0 执行到200。至少在前100次迭代中,循环2 的代码可以被融合到循环1 的代码中。这样增加了指令级的并行,同样也减少了总体迭代次数的1/3 。

       内核融合是循环融合的演变。一系列按顺序执行的内核,内核的元素可以被融合。调用两个连续的内核会在它们之间生成隐式地同步。内核融合技术如此有效的部分原因是它所带来的数据重用。从全局内存取出数据的速度很慢,大约为400~600 个时钟周期。一旦有数据存储在共享内存或寄存器中,那么就尽量地重用它。


六、共享内存和高速缓存的使用

       相比与全局内存,使用共享内存可以提供10:1 的速度提升。但是共享内存的大小是受限的,在费米/开普勒 设备上为48KB,而之前的设备则是16KB。

       在费米架构和开普勒架构上,我们有一个非常有趣的选择:可以配置共享内存以优先使用一级缓存(48KB一级缓存和16KB共享内存)或优先使用共享内存(48KB共享内存和16KB 一级缓存)。设备默认情况下是优先使用共享内存,因此你会有48KB的共享内存可用。这个设置并非是固定的,而是运行时设定的,因此每次内核调用时可以设置它。那些不适用共享内存的内核或者保持16KB 上限来确保与之前GPU兼容的内核,通常通过启动额外的32KB 缓存能显著的受益(10%-20%的性能提升),而在默认情况下是禁用的。配置如下:

         cudaFuncSetCacheConfig(cache_prefer, kernel_name);

       参数cache_prefer 设置为cudaFuncCachePreferShared,表示使用48KB 共享内存和16KB 一级缓存,而设置为cudaFuncCachePreferL1 时,表示48KB 一级缓存和16KB 共享存储内存。






以上是关于CUDA 学习(十七)优化策略2:内存因素的主要内容,如果未能解决你的问题,请参考以下文章

CUDA 学习(二十二)优化策略7: 自调优应用程序

CUDA 学习共享内存

CUDA 学习(十五)应用程序性能优化

CUDA 学习(十八)优化策略3:传输

CUDA 学习(二十)优化策略5: 算法

CUDA 学习(二十)优化策略5: 算法