从Cuda传输大量可变内存

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

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

问题是65535(数据数组中的块/项)*20000(每个项测试的总组合)=1310700000。这意味着我需要创建一个这样大小的数组来处理所有数据都是正匹配的可能性(这是极不可能的,创建
int-output[1310700000][30]
对于内存来说似乎很疯狂)。我被迫将其缩小,并发送更少的块进行处理,因为我不知道Cuda如何有效地写入链表或动态大小的列表(使用这种方法,它使用块*不同方式测试的数量将输出写入主机内存)

有更好的方法吗?Cuda能否以某种方式写入非块ID派生的空闲内存?当我在CPU上测试这个进程时,只有不到10%的项数组具有正匹配,因此每次向内核发送工作时,我都不太可能使用这么多内存

p、 我在上面看,虽然这正是我在做的,但如果它让人困惑,那么另一种思考方式(不完全是我在做什么,但足以理解这个问题)是我发送20000个数组(每个数组包含65535个项),并将每个项与其他数组中的对等项相加,如果总数等于一个数字(如200-210)然后我想知道为得到匹配结果而添加的数字。如果数字的范围很广,那么不是所有的数字都匹配,但是使用我的方法,我被迫malloc大量的内存。我可以用更少的内存捕获结果吗?我目前的方法是malloc尽可能多地使用空闲内存,但我被迫运行更少的块这是没有效率的(我希望一次运行尽可能多的块和线程,因为我喜欢Cuda组织和运行块的方式)。是否有任何Cuda或C技巧可供我使用,或者我被最大可能的结果所困扰(并购买更多内存)?

正如Roger Dahl的伟大: 您正在寻找的功能称为流压缩

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


然而,考虑到一种更常见的情况,即有相当多的结果,最好的解决方案是将压缩操作作为一个单独的步骤来执行。一种方法是使用推力::复制_if。有关更多背景信息,请参阅此问题。

几行代码如何?如果正匹配数很少,我使用的替代过程是在中描述可能是一个很好的选择。你每次都会将索引增加30。嘿@wallyk有什么不清楚的地方我可以解释更多吗?或者如果你觉得需要代码,那么我可以创建一个sperate示例(因为我的实际代码库相当大,并且依赖于其他文件,我觉得这会更混乱,然后会更有用).谢谢@RogerDahl你又救了一天!我会检查你的答案并让你知道结果如何(我以前看到过,但没有意识到它适用于我的问题)。@harrism我认为罗杰斯的答案会起作用。我已经跑了很多次了,还没有机会实现这一点。我会在周末做这件事,并向你汇报(如果罗杰没有写答案,那么我会写下我所做的步骤作为答案)。