我有一系列M
单通道图像,每个大小为NxN
,连续存储在设备内存阵列中。(N
不是 2 的幂。)因此,数组的长度为MxNxN
。我需要找到每个图像的所有像素的总和。因此,输出是M
值,每个图像一个。
我正在生成一个附加数组,该数组保存每个像素的图像索引,并将该索引reduce_by_key
用于每个图像(片段)。这reduce_by_key
似乎很慢,比我在这些像素上所做的一切都花费更多的时间。
有没有更快的方法来完成这个分段缩减和,其中段的大小都相同?
OpenCV 提供了一个使用 CUDA 实现的矩阵缩减 API。你可以在这里找到它。
http://docs.opencv.org/modules/gpu/doc/matrix_reductions.html#gpu-reduce
如果您不想包含额外的 3rd 方库,则可以使用 cublas。在这种情况下,您的任务可以用 matlab 代码表示,如下所示。
result(1:M) = sum(images(1:N*N, 1:M), 1);
这相当于
result(1:M) = ones(1, N*N) * images(1:N*N, 1:M);
这是一个矩阵向量乘法运算,可以cublas<t>gemv()
通过 CUBLAS 提供的 BLAS 2 函数有效地完成。
http://docs.nvidia.com/cuda/cublas/index.html#cublas-lt-t-gt-gemv
另一方面,reduce_by_key()
用于您的任务不需要生成额外的图像索引数组。Thrust 中的花哨的迭代器是针对这种情况设计的,以减少全局内存带宽需求。
有关详细信息,请参阅此答案。