CUDA内存访问模式

本文探讨了GPU编程中如何最大化利用全局内存带宽,包括对齐与合并内存访问以减少事务次数,以及CPU与GPU的一级缓存特性。还介绍了AoS和SoA两种数组结构体存储方式对GPU性能的影响,强调了并行编程中SoA模式的优势。
摘要由CSDN通过智能技术生成

大多数设备端数据访问都是从全局内存开始的,并且多数GPU应用程序容易受内存带宽的限制。因此,最大限度的利用全局内存带宽是调控核函数性能的基本。

对齐与合并访问

如图,所有的应用程序数据最初存在于DRAM上,也就是物理设备内存上。核函数的内存请求通常是在DRAM设备和片上内存间以128字节或32字节内存事务来实现的。

所有对全局内存的访问都会通过二级缓存,也有许多访问会通过一级缓存,这取决于访问类型和GPU架构。如果都用到,就是128字节内存事务;如果只用了二级缓存,那么该内存访问是由一个32字节的内存事务实现的。

内存事务(Memory Transaction)指的是对内存进行的读取或写入操作。在GPU编程中,内存事务通常指的是对全局内存或共享内存的读取或写入操作,这些操作可以由单个线程或线程组(线程束)执行。

对齐的概念与C++类中的内存对齐概念相似,为了避免重复的读取数据,需要将数据在内存中对齐。

合并是指将多个内存事务合并为一个事务,合并通常发生在多个线程或线程束同时访问连续内存地址时。如果这些访问可以被合并为一个更大的内存事务,GPU可以更有效地利用内存系统的带宽和并行性。合并通常由GPU自动完成

全局内存读取

在SM中,数据通过以下3种缓存/缓冲路径进行传输,具体使用哪种方式取决于引用了哪种类型的设备内存

  • 一级和二级缓存
  • 常量缓存
  • 只读缓存

一级和二级缓存是默认路径。

CPU一级缓存和GPU一级缓存的差异

CPU一级缓存优化了时间和空间局部性。GPU一级缓存是专门为了空间局部性而不是为了时间局部性设计的。频繁访问一个一级缓存的内存位置不会增加数据留在缓存中的概率。

时间局部性和空间局部性

时间局部性认为如果一个数据位置被引用,那么该数据在较短的时间周期内很可能会被再次引用,随着时间,该数据被引用的可能性逐渐降低。空间局部性认为,如果一个位置被引用,则附近的位置也可能会被引用。

全局内存写入

一级缓存不能用在费米或开普勒GPU上进行存储操作,在发送到设备内存之前存储操作只通过二级缓存。

结构体数组和数组结构体

数组结构体(AoS)

struct S{
    float x;
    float y;
};

struct S myAoS[N];

结构体数组(SoA)

struct S{
    float x[N];
    float y[N];
};

画个图说明这两种结构体存储数据的区别

用AOS模式在GPU上存储一个只使用x字段的应用程序,将导致50%的带宽损失。y值在32字节或128字节缓存行上隐式的被加载。AOS模式也浪费了二级缓存的空间在不需要的y值上。

相比之下,SOA模式存储数据,可以更好的提高资源的利用率。

在并行编程中,更倾向于使用SOA模式。因为数据元素是为全局内存的有效合并访问而预先准备好的,而被相同内存操作引用的同字段数据元素在存储时是彼此相邻的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值