2

我需要在 CUDA 中解码 RLE,并且我一直在尝试考虑将 RLE 扩展为包含我所有值的列表的最有效方法。所以假设我的值是 2、3、4,我的运行是 3、3、1,我想将其扩展到 2、2、2、3、3、3、4。

起初我以为我可以使用cudaMemset,但现在我很确定启动内核并且我拥有 CUDA Compute Capability 3.0 所以即使为每个值/运行对启动新内核可能不是低效的,我也没有可用的动态并行性去做这个。

所以我想知道这个解决方案在我去实施它之前是否合理,因为如果你不聪明的话,有很多事情最终无法在 CUDA 上运行良好。cudaMalloc制作一个将cudaMemCpy调用到目的地的内核是否合理?我可以很容易地计算前缀总和,以知道将内存复制到哪里和从哪里复制,并使我所有的阅读至少合并。我担心的是打电话cudaMalloc等等cudaMemCpy很多次。

另一种可能的选择是将这些值写入共享内存,然后将它们复制到全局内存。我想知道我的第一个解决方案是否应该有效并且有效,或者我是否必须执行后者。

4

2 回答 2

3

您不想考虑为每个值/运行对执行单独的操作(例如cudaMalloc,或)。cudaMemset

在计算运行序列上的前缀和之后,前缀和中的最后一个值将是总分配大小。cudaMalloc将其用于整个最终扩展序列的单个操作。

一旦分配了必要的空间并计算了前缀总和,实际的扩展就非常简单了。

如果你想要一个快速的原型,推力可以让这很容易。一个示例代码

于 2016-04-18T15:36:13.133 回答
0

@RobertCrovella 当然是正确的,但如果您有余地稍微调整压缩方案,您可以在效率方面走得更远。

对不起,自我插入,但您可能对我自己的运行长度编码变体的实现感兴趣,并在输入中添加了输出位置的锚定(例如“在哪个偏移中我们有第2048个元素?”);这允许更公平地将工作分配给线程块,并避免需要完整的前缀和。它仍在进行中,因此在撰写本文时,我只能在 336 GB/秒的内存带宽卡 (Titan X) 上获得约 34 GB/秒的速度,但它非常有用。

于 2017-02-16T10:23:54.507 回答