【问题标题】:CUDA: How to find index of extrema in sub matrices?CUDA:如何找到子矩阵中的极值索引?
【发布时间】:2014-02-24 10:51:34
【问题描述】:

我在 GPU 内存中有一个大型矩形矩阵 NxM,以逐行表示形式存储为一维数组。假设这个矩阵实际上是由大小为 nxm 的子矩阵组成的。为简单起见,假设 N 是 n 的倍数并且与 M 和 m 相同。比方说,数组的数据类型是浮点数或双精度数。

在每个子矩阵中找到极值索引的有效方法是什么?例如,如何找到每个子矩阵的最大元素的一维索引并将这些索引写在某个数组中。

【问题讨论】:

  • 最合适的解决方案将取决于n 相对于warp 大小的大小。没有通用的解决方案。如果 n 接近 N,那么 cublasIsamin 可能与您自己编写的任何内容一样有效。
  • @talonmies 我试图在我的回答中指出这个重要的区别(无论是 N=n*2 还是 N=n*10000)。虽然cublasIsamin 听起来是我草拟的第二种方法的好选择,但问题是它仅在 1D 数组上运行(在 incx 中给出了可能的步幅,但仍然是 1D) - 所以它不适用于 2D 子矩阵

标签: cuda


【解决方案1】:

我很难想象我会如此自信(或傲慢?)说一个特定的解决方案是“最有效的方式”做某事。

但是,一些想法(没有声称涵盖“最有效”的解决方案):

我认为基本上有两种“正交”的方法来解决这个问题

  • 对于所有并行的子矩阵:依次求极值
  • 依次对所有子矩阵:并行求极值

哪个更合适的问题可能取决于矩阵的大小。您提到 “N 是 n 的倍数”(对于 M 和 m 类似)。假设大小为M x N 的矩阵由大小为m x n 的子矩阵a*b 组成。

对于第一种方法,可以简单地让每个线程处理一个子矩阵,使用类似的简单循环

for (all elements of my sub-matrix) max = element > max ? element : max;

这里的先决条件是a*b“相当大”。也就是说,当你可以为 10000 个子矩阵启动这个内核时,这已经可以带来很好的加速了。

与此相反,在第二种方法中,每个内核(及其所有线程)将处理一个子矩阵。在这种情况下,内核可以是标准的“缩减”内核。 (归约通常作为“计算数组元素的和/积”的示例,但它适用于任何二进制关联运算,因此无需计算和或积,基本上可以使用相同的内核进行计算最小值或最大值)。所以内核将为每个子矩阵启动,这只有在子矩阵“相当大”时才有意义。

但是,在两种情况下,都必须考虑一般性能准则。特别是,由于在这种情况下,操作显然受内存限制(而不是计算限制),因此必须确保对全局内存(即矩阵本身)的访问是合并的,并且占用由内核创建的尽可能高。

编辑:当然,可以考虑以某种方式组合这些方法,但我认为它们至少显示了可用选项空间中最重要的方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    相关资源
    最近更新 更多