【问题标题】:Is it faster to sum the rows or columns of a matrix with CUDA?用 CUDA 对矩阵的行或列求和会更快吗?
【发布时间】:2013-04-30 16:45:32
【问题描述】:

我想计算 m x n 矩阵 A 的行和,或等效地其转置 A' 的列和(我在内存中都有,所以 A'我在计算上没有花费任何额外的费用)。我计划启动m 线程,每个线程都可以遍历An 列,或A'n 行。如果我们假设矩阵以列主要格式(即与 CUBLAS 一样)存储,哪种方法会更快?

我目前的想法(关于合并内存访问):

如果我行求和,那么同一块中的线程将在每次迭代时从相邻的内存位置读取。然而同样,如果我改为列求和,那么 每个线程 将遍历一个连续的内存块。因此,如果我有线程 123 的同一块,它们的内存访问将如下所示(假设 column-major storage):

1 2 3 ... 1 2 3 ... 1 2 3 ... for row-sums
1 1 1 ... 2 2 2 ... 3 3 3 ... for column-sums
  • 但这并不能告诉我哪个会更快。
  • 它也没有考虑到块级的行为(即,如果第一个块启动对行求和1-32,是否保证启动的第二个块对行求和33-64?)

【问题讨论】:

    标签: performance matrix cuda sum gpgpu


    【解决方案1】:

    “同一块中的线程将在每次迭代时从相邻的内存位置读取”

    更快。这几乎就是合并访问的定义。

    【讨论】:

      【解决方案2】:

      对于单线程:

      for (i = 0 to size)
         for (j = 0 to size)
            array[i][j]
      

      会比

      for (i = 0 to size)
         for (j = 0 to size)
            array[j][i]
      

      因为在内存中每一行都是在内存中连续布局的。

      但对于多线程来说,它并不是那么明确。如果您在 M 核 CPU 上生成 M 个线程,那么谁知道会发生什么。您的 L1 缓存将是特定于核心的,但假设您的整体矩阵大于缓存的大小,您的 L3 共享缓存可能不会很有帮助。我认为说有太多可能性无法做出明确的答案是不公平的。一些想法:

      【讨论】:

      • 谢谢,但我在 GPU 上进行计算,并且我的矩阵存储使得每个 column 在内存中连续布局。
      • 这个问题并不是关于 M 核 CPU 的一般性问题。在 CUDA GPU 的情况下,多个线程处于活动状态,内存带宽的最佳使用发生在合并访问。带宽受限代码的最佳整体吞吐量将在内存带宽的最佳使用情况下发生。多个元素的总和将是带宽受限的代码。所以我认为一个明确的答案是可能的。当应用于 CUDA GPU 时,您的其他一些 cmets 不适用或错误,例如“产生的线程数多于内核数......”这通常是您想要对 CUDA GPU 执行的操作。
      • 我认为你没有注意到这是一个 CUDA GPU 编程问题?
      猜你喜欢
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 2011-04-28
      • 2015-06-17
      • 2018-03-10
      • 1970-01-01
      相关资源
      最近更新 更多