【问题标题】:How to shuffle data efficiently within device memory?如何在设备内存中有效地洗牌?
【发布时间】:2013-08-27 07:17:34
【问题描述】:

问题

在设备全局内存中移动许多随机(非合并)值时,哪种方式最有效?

注意:许多值都在 > 500 中。

上下文

我从事 GPU 的遗传算法实现已经有一段时间了,我一直在努力在我的框架的灵活性和 GPU 架构的微优化之间挣扎。 GA 数据始终驻留在 GPU 中。只有最佳代解决方案被复制到主机内存中。

详细场景

我正在优化迁移功能。这里基本上很少有数据在设备全局内存中被洗牌。但是我的数据顺序以这种方式合并为 GA 运算符内核线程的内存访问方案,这使得洗牌一对“基因组”,一个跨步的问题,单个 FLOAT 值,并以相同的跨步方式将它们与另一个基因组交换。

已知解决方案

问题不在于内存带宽,而是调用延迟和线程阻塞导致进程停滞的问题。

  1. 我编写了几个设备内核,其功能只是在地址之间移动值。这将启动一个内核(占用率非常低、代码分散和随机内存访问......因此它运行的小代码将被序列化),但只需对设备进行两次内核调用即可完成工作。

    • 第一个内核将值复制到缓冲区数组。
    • 第二个内核交换值。
  2. 我知道我可以对每个值使用 cudaMemcpy,但这需要多次调用 cudaMemCpy,我认为这是 同步的来电

简化代码示例:

int needed_genome_idx = 0; // Some random index.
for(int nth_gene = 0; nth_gene < num_genes; ++nthgene)
{
  cudaMemcpy(genomes_buffer + nth_gene,
             src + needed_genome_idx + nth_gene * stride_size, // stride_size being a big number, usually equal to the size of the GA population.
             sizeof(float),
             cudaMemCpyDeviceToDevice);
}

这是一个可行的解决方案吗?使用 cudaMemCpyAsync 会提高性能吗?

有没有更好的方式,或者至少更优雅的方式来做这样的内存操作?

【问题讨论】:

  • 您的基因组载体的长度是多少?您需要洗牌多少对基因组?当您改组一对基因组向量时,应该交换向量中的多少元素?这些元素是如何选择的? (随机还是范围?)您的基因组是如何存储在全局内存中的?能否提供更具体的代码示例?
  • 只复制 1 个浮点数和 1 个 cudaMemcpy() 调用显然是一种非常低效的方法
  • 我正在实现框架,并且我的目标是灵活性。 GPU 实现的本质要求使用大量岛屿、大量人口和高维基因组进行 GA 设置,因此使用 GPU 而不是 CPU 是有意义的。因此,您要求的这些细节会有所不同。但通常我使用以下:基因组向量将在 10-50 范围内,要洗牌的基因组很可能是每个岛一个,~16(但可能是更大的数字),整个向量将是在每个迁移操作中交换(通常在一定数量的代之后)。
  • 如果您仍然一次复制一个浮点数,则不会有太大差异。一般cudaMemcpy()/cmdaMemcpyAsync()会在数据大小> 100 KBbytes时达到其最大速度,如此处D2D复制速度所示stackoverflow.com/questions/17729351/…
  • cudaMemcpyDeviceToDevice 可能比编写内核来执行相同操作要慢,请参阅CUDA Device To Device transfer expensive。您的代码对我来说不是很清楚:genomes_buffersrc 未定义,needed_genome_idx 声称是随机的,但设置为 0。您能否更清楚地了解“迁移”对您意味着什么?

标签: c++ c cuda parallel-processing gpgpu


【解决方案1】:

你可以尝试写一个内核来完成shuffle,可能比调用cudaMemcpy这么多次效率更高。

【讨论】:

    猜你喜欢
    • 2013-11-05
    • 2014-11-03
    • 1970-01-01
    • 2018-03-16
    • 2013-01-15
    • 2013-09-02
    • 1970-01-01
    • 2021-03-13
    • 2011-07-28
    相关资源
    最近更新 更多