我有一系列M
个单通道图像,每个图像大小为NxN
,连续存储在设备存储器阵列中。 (N
不是2的幂。)因此,数组的长度为MxNxN
。我需要找到每个图像的所有像素的总和。因此,输出为M
值,每个图像一个。
我正在生成一个附加数组,用于保存每个像素的图像索引,并为每个图像(段)使用此索引reduce_by_key
。这个reduce_by_key
似乎相当慢,比我在这些像素上所做的其他事情花费的时间更长。
是否有更快的方法来执行此分段缩减总和,其中段的大小都相同?
答案 0 :(得分:1)
OpenCV提供了使用CUDA实现的矩阵缩减API。你可以在这里找到它。
http://docs.opencv.org/modules/gpu/doc/matrix_reductions.html#gpu-reduce
如果您不想包含额外的第三方库,可以使用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提供的BLAS 2函数cublas<t>gemv()
有效地完成。
http://docs.nvidia.com/cuda/cublas/index.html#cublas-lt-t-gt-gemv
另一方面,使用reduce_by_key()
执行任务不需要生成额外的图像索引数组。 Thrust中的花式迭代器专为这种情况而设计,以减少全局内存带宽需求。
有关详细信息,请参阅此答案。