如何在设备内存中有效地混洗数据?

时间:2013-08-24 07:58:52

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

问题

在设备全局内存中移动许多随机(非合并)值时,这是最有效的方法吗?

注意:>中的许多值500。

上下文

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

详细方案

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

已知解决方案

问题不在于内存带宽,而在于调用延迟和线程阻塞问题。

  1. 我写了几个设备内核,其功能仅仅是在地址之间移动值。这将启动一个内核(具有非常低的占用率,不同的代码和随机内存访问...因此它运行的小代码将被序列化),但只能对设备进行两次内核调用。

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

  3. 简化代码示例:

    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 个答案:

答案 0 :(得分:2)

你可以尝试编写一个内核来完成shuffle,也许比调用cudaMemcpy好多次。