6

问题

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

注意:许多值 > 500。

语境

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

详细场景

我正在优化迁移功能。这里基本上很少有数据在设备 Global Memory中洗牌。但是我的数据顺序是这样的,它与 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会提高性能吗?

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

4

1 回答 1

2

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

于 2013-09-02T07:41:10.913 回答