内存事务和内存指令的区别

背景

当一个warp去执行一个获取内存的指令时候,很重要一点是要考虑一下线程束中每个线程访问的内存位置。

初步理解

A memory “request” is an instruction which accesses memory, and a “transaction” is the movement of a unit of data between two regions of memory. 这段话意思是,一个内存请求是一个获取内存的指令,一个内存事务是在两个内存范围(比如L1和dram,或者是SM和L1)之间的数据单元移动一次。这个涉及到相关内存合并访问的问题,比如一个warp中,每个线程获取一个4字节的数据,假如这32个线程获取的数据在连续的一排,且第一个位置是0开头,那么这一个warp指令(指令最小单位是一个warp)最终会有一个内存事务(比如一个数据单元大小(cache line)是128字节)发生,如果这个32个线程所要获取的数据分布在五湖四海,那么就需要32个事务。因为每一个内存事务,简单说就是一个邮递员,他每次可以携带一封信从A到B,信最大可以携带128字节的信息量,通勤一次时间200天,所以你是愿意写一封128字节的信,还是写32封4字节的信,方案不言而喻。参考博客

深度理解

我们知道一个global获取指令,在硬件上是先去L1或者L2缓存上找数据,找不到的话会从device memory上找数据,然后放到L1/L2上,然后导入到kernel上使用,所以我们常用的一个profile的指令gld_transactions_per_request到底是啥意思,这里的内存事务是指从L1/L2到kernel里,还是说设备内存到L1/L2的?此外还有一个dram_read_transactions的指令又是啥意思?这里我们参考一个解释,由一个warp发出的一个ldg指令(获取global memory指令),首先去L1/L2 cache中获取,如果拿到数据(gld_transactions)了,就不会去dram上去获取数据(dram_read_transactions),下一面一张图我觉得很好解释了相关意义:
在这里插入图片描述
更加具体解释,可以参考nvidia的文档链接和stackflow的大佬回答

这里补充一个小知识,对于cache line也不是固定的,比如L1的cache line是128字节,假如一个warp访问的数据是连续对齐的且每个线程获取8个字节,那么就需要2个内存事务,这个是正常的,但是如果这32个线程全部访问一个同一个地址数据,那么实际打印出发现只有一个内存事务,你可以理解cache line变成了256字节,其实只是软件映射的我觉得物理上还是128,这个在实际测试遇到了要理解。

实验代码

结论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值