1. CUDA全局内存基础概念
全局内存(Global Memory)是CUDA编程中最基础也是最常用的内存类型,它相当于GPU的"主内存",具有以下关键特性:
- 容量大(通常为GB级别)
- 延迟高(约400-800个时钟周期)
- 带宽高(现代GPU可达数百GB/s)
- 生命周期与应用程序相同
- 可被所有线程访问(全局可见)
在硬件层面,全局内存位于GPU板载的DRAM芯片上,通过内存控制器与流式多处理器(SM)连接。当我们在CUDA内核中声明一个设备变量(使用__device__修饰符)或调用cudaMalloc()分配内存时,分配的就是全局内存。
注意:全局内存的分配单位是256字节对齐的,这意味着即使你只申请1字节,实际也会占用256字节的内存空间。这个特性对性能优化非常重要。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 全局内存的访问模式与合并访问
2.1 内存事务的基本原理
GPU访问全局内存时,并不是按字节为单位,而是以"事务"(Transaction)为单位。根据GPU的计算能力不同,支持32字节、64字节或128字节的内存事务。例如,计算能力1.0的设备(如Tesla C870)只支持32字节事务。
当一组线程(称为warp,32个线程)访问内存时,GPU会尽量将这些访问合并为最少数量的事务,这就是所谓的"合并访问"(Coalesced Access)。合并程度越高,内存带宽利用率就越高。
2.2 合并访问的条件
实现完全合并访问需要满足以下条件:
- 线程访问的内存地址必须连续
- 起始地址必须对齐到事务大小的整数倍(如32字节对齐)
- 访问模式必须是有序的(即threadIdx.x与内存地址顺序一致)
对于计算能力1.0/1.1的设备,合并访问的要求更为严格:
- 半warp(16个线程)的访问必须对齐且连续
- 否则会退化为16个独立的32字节事务
2.3 不同计算能力设备的差异
c复制// 计算能力1.0/1.1设备上的非合并访问示例
__global__ void bad_access(float *data) {
int idx = threadIdx.x + blockIdx.x * blockDim.x;
float value = data[idx]; /
