Memory management CUDA 5.0内存对齐和合并访问

Memory management CUDA 5.0内存对齐和合并访问,memory-management,cuda,Memory Management,Cuda,我有一个2D主机阵列,有10行96列。我将此阵列线性加载到cuda设备全局内存,即第1行、第2行、第3行。。。第10行 数组的类型为float。在我的内核中,每个线程从设备全局内存访问一个浮点值 The BLOCK_SIZE I use is = 96 The GRID_DIM I use is = 10 现在,我从“CUDAC编程指南”中了解到,对于合并访问,我使用的模式是正确的,通过warp连续访问内存位置。但是有一个关于内存128字节内存对齐的条款。我不明白 Q1)128字节内存对齐

我有一个2D主机阵列,有10行96列。我将此阵列线性加载到cuda设备全局内存,即第1行、第2行、第3行。。。第10行

数组的类型为float。在我的内核中,每个线程从设备全局内存访问一个浮点值

 The BLOCK_SIZE I use is = 96
 The GRID_DIM I use is = 10
现在,我从“CUDAC编程指南”中了解到,对于合并访问,我使用的模式是正确的,通过warp连续访问内存位置。但是有一个关于内存128字节内存对齐的条款。我不明白

Q1)128字节内存对齐;这是否意味着扭曲中的每个线程都应该访问从地址0x00(例如)到0x80的4个字节

问题2)那么在这种情况下,我是否会进行未恢复的访问


我的理解是:一个线程应该进行一次内存访问,访问长度应该是4字节,从地址范围(例如0x00到0x80)开始。如果来自扭曲的线程访问其外部的位置,则为非协调访问。

从全局内存加载通常以128字节为一组,按128字节边界对齐。合并内存访问意味着您将所有从扭曲到一块128字节的访问保持在一起。(在旧卡中,必须按照线程id的顺序访问内存,但新卡不再有此要求。)

如果warp中的32个线程都读取一个浮点值,那么您将从全局内存中总共读取128个字节。如果内存正确对齐,则所有读取都将来自同一块。如果“对齐”处于禁用状态,则需要两次读取。如果执行类似于
a[32*i]
的操作,则每次访问都将来自全局内存中不同的128字节块,这将非常缓慢

访问哪个块并不重要,只要扭曲中的所有线程都访问同一块

如果您有一个96个浮点数组,那么如果warp中索引为
i
的每个线程访问
a[i]
,它将是一个联合读取。与
a[i+32]
a[i+64]
相同

因此,Q1的答案是,所有线程都需要保持在长度为128字节的同一块内,并在128字节边界上对齐

问题2的答案是,如果数组正确对齐,并且访问的形式为
a[32*x+i]
i
线程id和
x
所有线程相同的任何整数,则访问将合并


根据《编程指南》第5.3.2.1.1节,内存始终在至少256字节的边界上对齐,因此使用
cudamaloc
创建的数组始终正确对齐。

谢谢@Jeffrey。它澄清了我所有的疑问。