我的结构为
struct Point
{
int x;
int y;
float val;
}
我打算用这个结构来表示稀疏矩阵(我知道 CUSPARSE和CUSP,但我打算用它来执行一些测试 推力)并使用推力算法执行操作。
从我在CUDA编程教程中学到的,它总是如此 建议使用数组结构而不是结构数组 更好的记忆合并。
如果是这种情况,那么如果我使用上面提到的结构在device_vector中存储非零(大约数百万),那么这个device_vector在使用推力算法时是否会在GPU内部使用未对齐的内存访问?
我问这个是因为我可能需要在其中访问不规则的步幅 device_vector并通过传递多个来执行算法操作 功能对象。
它是否会像在数组结构上运行的自定义内核一样高效?
感谢。
答案 0 :(得分:4)
NVIDIA CUDA设备可以有效地访问4,8和16字节结构,假设合并的内存访问模式。为此,CUDA标头定义了您可以使用的结构int2
,int4
,float2
,float4
等。它们被定义为具有高效对齐,因此我建议使用
typedef int2 Point;
当对这些小结构的数组的所有内存访问在warp中的线程(例如合并)中是顺序的,并且每个struct元素中的所有数据都由读取/写入它的线程使用时,那么这种类型的AOS访问是效率很高。实际上,使用这样的向量结构通常会导致比标量数据访问更高的内存吞吐量,因为飞行中的内存事务会增加。
Thrust提供zip_iterator
专门用于操作SOA数据的方便性和(编码)效率,就好像它是AOS数据一样。因此,虽然小结构在直接CUDA C ++中是有效的,但在使用Thrust时,您可以选择为每个结构成员使用单独的device_vector
,并在调用zip_iterator
之前使用transform
将它们压缩在一起。和其他推力算法。 Thrust示例代码中包含了一些示例。