4

Cuda 很棒,我正在疯狂地使用它,但我没有充分发挥她的潜力,因为我在传输内存时遇到了问题,并且想知道是否有更好的方法来获取可变数量的内存。基本上我将 65535 项数组发送到 Cuda 中,Cuda 以大约 20,000 种不同的方式分析每个数据项,如果我的程序逻辑中有匹配项,那么它会保存一个 30 个 int 列表作为结果。想想我分析每个不同组合然后查看总数的逻辑,如果总数等于我正在寻找的数字,那么它会保存结果(这是每个分析项目的 30 int 列表)。

问题是 65535(数据数组中的块/项目)* 20000(每个项目测试的总组合)= 1,310,700,000。这意味着我需要创建一个该大小的数组来处理所有数据都将是正匹配的机会(这极不可能并且创建int output[1310700000][30]似乎对内存来说很疯狂)。我被迫使它更小并发送更少的块来处理,因为我不知道 Cuda 是否可以有效地写入链表或动态大小的列表(通过这种方法,它使用块将输出写入主机内存* number_of_different_way_tests)。

有一个更好的方法吗?Cuda 可以以某种方式写入不是从 blockid 派生的空闲内存吗?当我在 CPU 上测试这个过程时,只有不到 10% 的项目数组有一个正匹配,所以我每次向内核发送工作时都不太可能使用这么多内存。

ps 我在上面看,虽然它正是我在做的事情,如果它令人困惑,那么另一种思考方式(不完全是我在做什么,但足以理解问题)是我发送 20,000 个数组(那个每个包含 65,535 个项目)并将每个项目与其对等项添加到其他数组中,如果总数等于一个数字(比如 200-210),那么我想知道它添加的数字以获得匹配结果。如果数字范围很广,那么并非所有数字都匹配,但使用我的方法,我不得不 malloc 大量内存。我可以通过分配更少的内存来捕获结果吗?我目前的方法是尽可能多地使用 malloc,但我不得不运行更少的块,这不是有效的(我想一次运行尽可能多的块和线程,因为我喜欢 Cuda 组织和运行块的方式) .

4

1 回答 1

0

正如 Per Roger Dahl 的最佳答案:您正在寻找的功能称为流压缩。

您可能确实需要提供一个数组,其中每个线程包含 4 个解决方案的空间,因为尝试以紧凑的形式直接存储结果可能会在线程之间创建如此多的依赖关系,以至于能够将更少的数据复制回所获得的性能主机因内核执行时间较长而丢失。例外情况是,如果几乎所有线程都找不到解决方案。在这种情况下,您也许可以使用原子操作来维护数组的索引。因此,对于找到的每个解决方案,您将其存储在索引处的数组中,然后使用原子操作来增加索引。我认为为此使用 atomicAdd() 是安全的。在存储结果之前,线程将使用 atomicAdd() 将索引增加一。atomicAdd() 返回旧值,

但是,考虑到更常见的情况,即有相当数量的结果,最好的解决方案是将压缩操作作为单独的步骤执行。一种方法是使用thrust::copy_if。有关更多背景信息,请参阅此问题。

于 2012-07-22T20:14:29.303 回答