cuda - 在 CUDA 中,什么是内存合并,它是如何实现的?

标签 cuda definition memory-access

CUDA 全局内存事务中的“合并”是什么?即使读完我的 CUDA 指南后我还是无法理解。怎么做?在CUDA编程指南矩阵示例中,逐行访问矩阵称为“合并”,或者逐列访问矩阵称为合并? 哪个是正确的,为什么?

最佳答案

此信息可能仅适用于计算能力 1.x 或 cuda 2.0。更新的架构和 cuda 3.0 具有更复杂的全局内存访问,事实上,甚至没有为这些芯片分析“合并的全局负载”。

此外,此逻辑可以应用于共享内存以避免存储体冲突。

<小时/>

合并内存事务是一种半扭曲中的所有线程同时访问全局内存的事务。这太简单了,但正确的方法是让连续的线程访问连续的内存地址。

因此,如果线程 0、1、2 和 3 读取全局内存 0x0、0x4、0x8 和 0xc,则它应该是合并读取。

在矩阵示例中,请记住您希望矩阵线性驻留在内存中。您可以按照自己的意愿执行此操作,并且您的内存访问应该反射(reflect)矩阵的布局方式。所以,下面的 3x4 矩阵

0 1 2 3
4 5 6 7
8 9 a b

可以像这样一行一行地完成,以便 (r,c) 映射到内存 (r*4 + c)

0 1 2 3 4 5 6 7 8 9 a b

假设您需要访问一次元素,并假设您有四个线程。哪些线程将用于哪些元素?可能是这样

thread 0:  0, 1, 2
thread 1:  3, 4, 5
thread 2:  6, 7, 8
thread 3:  9, a, b

thread 0:  0, 4, 8
thread 1:  1, 5, 9
thread 2:  2, 6, a
thread 3:  3, 7, b

哪个更好?哪个会导致合并读取,哪个不会?

无论哪种方式,每个线程都会进行三次访问。我们先看第一次访问,看看线程是否连续访问内存。在第一个选项中,第一次访问是0、3、6、9。不连续,不合并。第二个选项,是0、1、2、3。连续!合体了!耶!

最好的方法可能是编写内核,然后对其进行分析以查看是否有非合并的全局加载和存储。

关于cuda - 在 CUDA 中,什么是内存合并,它是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5041328/

相关文章:

C - 直接使用地址访问内存?

c++ - 内存访问冲突错误c++

cuda - 尝试构建我的 CUDA 程序时出现错误 MSB4062

c++ - 使用 cuda 7.0 RC 中的 cusolver 进行特征值和特征向量计算

c++ - 在头文件中定义非内联函数时出现链接器错误?

python类对象定义

cuda - 插入cuda内核

c++ - CUDA:处理不同大小的数组

delphi - 从 Delphi 中的其他单元定义类型

go - 使用 Golang 读取随机内存位置