CUDA学习笔记2——全局内存的合理使用(以矩阵转置为例,讲述全局内存的合并访问以及__ldg())

文章探讨了CUDA编程中全局内存的合并与非合并访问策略,以及矩阵转置的不同实现方式对性能的影响。指出非合并读取和合并写入可能导致性能差异,特别是由于硬件特性(如帕斯卡架构的__ldg函数)在读取方面提供的缓存优势。

6. 全局内存的合理使用

6.1 全局内存的合并与非合并访问

对全局内存的访问会触发内存事务(memory transaction),也就是数据传输(data transfer)。在启用了L1缓存的情况下,对全局内存的读取首先尝试经过L1缓存;如果未命中,则尝试通过L2缓存;如果还未命中,则直接从DRAM读取。一次数据传输的数据量在默认情况下是32字节。

关于全局内存的访问模式,有合并(coalesced)与非合并(uncoalesced)两种。合并访问指的是一个warp对全局内存的一次访问请求导致最少数量的数据传输。定量的说,可以定义一个合并度(degree of coalescing),它等于warp请求的字节数除以该请求导致的所有数据传输处理的字节数。如果所有数据传输处理的数据都是该warp所需要的,那么合并度为100%,即合并访问。

举个栗子

考虑一个warp访问float类型的全局内存变量的情况,一个float占4字节,因此该warp请求128字节的数据。在理想情况下(合并度为100%时),这将仅触发128/32=4次数据传输。那么,什么情况下会触发多于4次的数据传输呢?(PS:在一次数据传输中,转移的一片内存的首地址一定是32的整数倍,例如一次数据传输只能从全局内存读取地址为0到31字节、32到63字节等片段的数据;使用CUDA运行时API分配的内存的首地址至少是256的整数倍。)

  • 不对齐的非合并访问

    __global__ void add_offset(float *x, float *y, float *z) {
         
         
        int tid = blockIdx.x * blockDim.x + threadIdx.x + 1;
        z[tid] = x[tid] + y[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值