【发布时间】:2016-07-11 02:13:51
【问题描述】:
我想知道分配主机和设备都可以访问的结构的最佳方法是什么。以下面的结构体为例:
struct Buff {
int * index;
Chunk * chunks;
}
其中 Chunk 是一个简单的数组结构:
struct Chunk {
int sas[CHUNK_SIZE];
int das[CHUNK_SIZE];
};
现在我首先为结构分配零拷贝内存,然后为结构成员分配零拷贝内存,如下所示:
Buff * my_buff;
// Allocate zero-copy memory for the struct (as the container)
checkCudaErrors(cudaHostAlloc(&my_buff, sizeof(Buff), cudaHostAllocMapped));
// Allocate zero-copy memory for index
checkCudaErrors(cudaHostAlloc(&my_buff->index, sizeof(int), cudaHostAllocMapped));
// Allocate zero-copy memory for the array of chunks
checkCudaErrors(cudaHostAlloc(&my_buff->chunks, sizeof(Chunk) * NUM_CHUNKS, cudaHostAllocMapped));
但是,我想知道是否有更有效的方法,例如统一内存中自动处理深拷贝的方式。
【问题讨论】:
-
我相信你的方法是最好的。我假设您正在使用 Tegra TK1 或 TX1。在这种情况下,为了获得最佳性能,您通常想要避免任何内存到内存的复制。零拷贝应该可以做到这一点。
-
@RobertCrovella 谢谢!是的,实际上,我与两者一起工作。作为后续问题:读/写 my_buff->index 需要多少次访问全局内存?我希望只有一个。
-
我认为
index没有任何意义。如果buff已经可以通过 GPU 访问,那么它的用途是什么? -
应该只有一个可以读写那个值。它实际上只是取消引用
my_buff指针的偏移量。但是,正如@talonmies 所指出的,index也是一个指针。因此,读取指针值需要一次访问,如果取消引用该指针,则需要再进行一次访问。所以一般来说,这些指针追踪方案对于 GPU 的使用并不是最佳的。通常的建议是扁平化此类结构,有效地从 AoS 转换为 SoA 方法。 -
@talonmies 你是对的!但原因是 cudaHostAlloc 将指针作为第一个参数,所以我认为这是唯一的方法!
标签: cuda