2

我正在处理图像立方体(450x450x1500)的大数据集。我有一个适用于单个数据元素的内核。每个数据元素产生 6 个中间结果(浮点数)。我的块由 1024 个线程组成。每个线程(6 个浮点数组)将 6 个中间结果存储在共享内存中。但是,现在我需要添加每个中间结果以产生总和(6 个总和值)。我没有足够的全局内存来将这 6 个浮点数组保存到全局内存,然后从主机代码中运行推力或任何其他库的缩减。

是否可以从共享内存中数组的内核函数内部调用任何缩减例程?

解决这个问题的最佳方法是什么?我是 CUDA 编程的新手,欢迎任何建议。

4

4 回答 4

2

这似乎不太可能:

我没有足够的全局内存来将这 6 个浮点数组保存到全局内存,然后从主机代码中运行推力或任何其他库的缩减。

我无法想象您如何有足够的空间将数据存储在共享内存中而不是全局内存中。

无论如何,CUB提供了可以从线程块中调用的缩减例程,并且可以对存储在共享内存中的数据进行操作。

或者您可以编写自己的减和代码。做起来并不难,关于它的问题有很多,比如这个

或者您可以调整cuda 示例代码

于 2013-09-17T21:54:59.877 回答
1

更新

看了所有评论后,我明白了,你需要做 450x450x6 次的缩减,而不是做 1 次或几次缩减。

在这种情况下,有更简单的解决方案。

您不需要为每个 1500 维向量实现相对复杂的并行归约。由于您已经有 450x450x6 向量要归约,您可以使用传统的串行归约方法并行归约所有这些向量。

您可以使用具有 16x16 线程的块来处理图像的特定区域,并使用具有 29x29 块的网格来覆盖整个 450x450 图像。

在每个线程中,您可以遍历 1500 帧。在每次迭代中,您可以先计算 6 个中间结果,然后将它们加到总和中。当你完成所有迭代时,你可以将 6 个和写入全局内存。

这样就完成了内核设计。并且不需要共享内存。

你会发现性能非常好。由于它是一个内存绑定操作,它不会比简单地访问一次所有图像立方体数据更长。

如果您没有足够的全局内存来存储整个立方体,您可以将其拆分为 [1500][225][225] 的 4 个子立方体,并在每个子立方体上调用内核例程。您唯一需要更改的是网格大小。

于 2013-09-18T02:40:06.440 回答
0

如果我理解正确,每个线程应该总结“仅”6浮动。

我不确定总体上是否值得通过并行减少来做到这一点,因为您将体验到性能提升。

如果您的目标是开普勒,如果您正确设置了块大小,则可以尝试使用shuffle操作,以便您的中间结果以某种方式适合流式多处理器的寄存器。

正如 Robert Crovella 所指出的,您关于存储中间结果的可能性的陈述似乎很奇怪,因为全局内存的数量肯定大于共享内存的数量。

于 2013-09-18T11:23:12.253 回答
0

看看这个,它彻底解释了 CUDA 的并行减少。

于 2013-09-17T23:41:34.767 回答