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%的item数组具有正匹配,所以每次我将工作发送到内核时,我都不太可能使用这么多内存。
P.S。我正在看上面,虽然它正是我正在做的,如果它令人困惑,那么另一种思考方式(不完全是我正在做的但是足以理解问题)是我发送20,000个数组(每个包含65,535项)并在其他数组中添加其对等项,如果总数等于一个数字(比如200-210),那么我想知道它为获得匹配结果而添加的数字。如果数字的范围非常广泛,那么并非所有数据都匹配,但使用我的方法,我被迫使用大量的内存。我可以通过mallocing更少的内存来捕获结果吗?我当前的方法是malloc,因为我有免费但我被迫运行更少的块效率不高(我想运行尽可能多的块和线程,因为我喜欢Cuda组织和运行块的方式) 。我可以使用任何Cuda或C技巧吗?或者我仍然坚持使用最大可能的结果(并购买更多的内存)?
答案 0 :(得分:0)
Per Roger Dahl的伟大answer: 您正在寻找的功能称为流压缩。
您可能需要提供一个包含每个线程4个解决方案空间的数组,因为尝试以紧凑的形式直接存储结果可能会在线程之间创建如此多的依赖关系,从而使得能够复制的性能增加更长的内核执行时间会丢失返回主机的数据。例外情况是,几乎所有线程都找不到解决方案。在这种情况下,您可以使用原子操作来维护数组的索引。因此,对于找到的每个解决方案,您将它存储在索引的数组中,然后使用原子操作来增加索引。我认为使用atomicAdd()是安全的。在存储结果之前,线程将使用atomicAdd()将索引增加一。 atomicAdd()返回旧值,线程可以使用旧值作为索引来存储结果。
然而,考虑到更常见的情况,即有相当数量的结果,最好的解决方案是将压缩操作作为单独的步骤执行。一种方法是使用thrust :: copy_if。有关更多背景信息,请参阅此问题。