我需要在CUDA中解码RLE,并且我一直在尝试考虑将RLE扩展到包含所有值的列表的最有效方法。所以说我的值是2,3,4,我的运行是3,3,1我想将它扩展为2,2,3,3,3,4。
起初我以为我可以使用cudaMemset
但我现在很确定启动内核并且我有CUDA Compute Capability 3.0所以即使为每个值/运行启动新内核可能效率不高也是如此对我没有可用的动态并行性。
因此,在我开始实施之前,我想知道这个解决方案是否合理,因为如果你不聪明,有很多东西最终在CUDA上运行不好。制作一个将cudaMalloc
然后cudaMemCpy调用到目的地的内核是否合理?我可以轻松地计算前缀总和,以了解将内存复制到何处的位置,并使我的所有阅读至少合并。我担心的是多次调用cudaMalloc
和cudaMemCpy
。
另一个可能的选择是将这些值写入共享内存,然后将这些值复制到全局内存。我想知道我的第一个解决方案是否应该有效,或者我是否必须做后者。
答案 0 :(得分:3)
您不希望考虑为每个值/运行对执行单独的操作(例如cudaMalloc
或cudaMemset
)。
在运行序列上计算前缀和后,前缀sum中的最后一个值将是总分配大小。将其用于整个最终扩展序列的单个cudaMalloc
操作。
一旦你分配了必要的空间,并计算了前缀和,实际的扩展非常简单。
如果你想要一个快速的原型,thrust可以让这很容易。它有an example code。
答案 1 :(得分:0)
@RobertCrovella当然是正确的,但如果你有足够的余地来调整你的压缩效果,你可以在效率方面更进一步。
对于自我填充感到抱歉,但您可能对运行长度编码变体的my own implementation感兴趣,并在输入中添加了输出位置的锚定(例如。"其中运行中我们有2048个元素的偏移量?");这允许更加公平地将工作分配给线程块,并避免需要完整的前缀和。它仍然是一个正在进行中的工作,因此在写入时我只能在336 GB /秒的内存带宽卡(Titan X)上获得~34 GB /秒,但它非常实用。