【问题标题】:CUDA - How to return results of unknown sizeCUDA - 如何返回未知大小的结果
【发布时间】:2015-01-14 13:27:24
【问题描述】:

我将一个大型二维数组(C 语言)传递给设备并确定所有可能的组合。例如:

A = 
id  val1 val2
1   100  200
2   400  800

Combination = 
id1  id2  sumval1  sumval2
1    2    500      1000

由于原始数组的大小,不可能存储和返回所有可能的组合。我想返回 sumval1 > 500 和 sumval2 > 1000 的所有组合。

我怎样才能将这个组合子集返回到要写入文件的主机;鉴于我不知道有多少组合符合条件?

【问题讨论】:

    标签: c arrays cuda combinations


    【解决方案1】:

    一些可能的方法:

    1. (从主机)分配您在 GPU 内存中剩余的任何空间用于缓冲区。如果超过了这个值,那么无论如何您都无法在一次传输中将所有组合传回。 (这可能会导致您使用 mtk99 提出的解决方案)。
    2. 使用内核内malloc 在设备上根据需要动态分配空间。完成组合创建后,将所有单独的组合收集到使用malloc 创建的单个缓冲区中。然后将此缓冲区的总大小和指向此缓冲区的指针传递回主机。然后主机使用cudaMalloc 分配该大小的新缓冲区,并启动内核以将数据从使用malloc 创建的缓冲区复制到使用cudaMalloc 创建的缓冲区。复制内核完成后,主机可以将数据从使用cudaMalloc 创建的缓冲区传回主机。

    我建议 1 可能是最好的方法,而无需了解您正在尝试做什么。在内核中malloc 在分配大量小分配时并不是特别快。此外,当使用内核malloc 时,请注意可以增加的默认大小限制 (8MB)。

    【讨论】:

    • 我喜欢分页的想法。我将为结果分配数组 R,但我应该如何索引数组?在 C 中,每次输入结果时我都会 i++。我会遇到使用相同 i 的所有线程的问题吗?
    • 是的,如果您有多个线程尝试更新单个缓冲区,则会出现问题。我的回答 here 对于让多个线程将数据推送到单个缓冲区中可能很有用。
    【解决方案2】:

    您可以对结果进行分页:

    • 创建一个修复结果数组(比如 Z 项)。

    • 不仅返回结果,还返回您停止的点(last_id1、last_id2)。

    • 在下一次调用时,根据您上次的结果传递一个新的起点(start_id1、start_id2)。

    您可以使用流来保持 GPU 加载。

    基于此,您甚至可以使用多个 GPU 分配计算。

    【讨论】:

    • 我喜欢分页的想法。我将为结果分配数组 R,但我应该如何索引数组?在 C 中,每次输入结果时我都会 i++。我会遇到使用相同 i 的所有线程的问题吗?
    • 你应该做流压缩,看看thrust::remove_if。在输出数组中生成尽可能多的组合。也许您需要输入是纹理,因此您可以使用谓词中的值而无需将它们复制到输出。运行流压缩并返回 last_id1 和 lastid_2。随着数据的推进,以不同的起点多次调用内核。
    猜你喜欢
    • 2018-05-26
    • 2015-09-09
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多