【问题标题】:allocating zero-copy struct on integrated GPU在集成 GPU 上分配零拷贝结构
【发布时间】: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


【解决方案1】:

这是我从上面的 cmets 中提取的问题的简短答案。

该方法的基本思想似乎没问题,在某种意义上,首先为结构分配零拷贝内存,然后为每个指针成员分配内存。

但是,在这种情况下,index 不应该是一个指针,因为my_buff 已经是 GPU 可访问的,并且将 index 作为指针将花费更多的全局内存访问。一般来说,指针追踪方案对于 GPU 的使用并不是最优的,通常的建议是扁平化这种结构,从而有效地从 AoS 转换为 SoA 方法。

【讨论】:

    猜你喜欢
    • 2022-01-15
    • 2021-03-07
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 2017-07-06
    • 1970-01-01
    相关资源
    最近更新 更多