【问题标题】:Coalesced memory access to 2d array with CUDA使用 CUDA 对二维数组的合并内存访问
【发布时间】:2015-05-01 13:28:41
【问题描述】:

我正在编写一段 CUDA C++ 代码,并且基本上需要每个线程通过行优先和列优先访问全局内存中的二维数组。具体来说,我需要每个线程块:

  • 生成它自己的一维数组(比如说,gridDim # of elements)
  • 将这些写入全局内存
  • 读取每个写入数组的第 n 个元素,其中 n 是块 ID。

在我看来,只有写入或读取可以合并,另一个将访问每个元素的单独缓存行(并且执行得非常糟糕)。我读过纹理内存有二维缓存机制,但不知道它是否可以用来改善这种情况。

顺便说一句,我使用的是 GTX 770,因此它是具有计算能力 3.0 的 GK104 Kepler 卡。

任何帮助或建议将不胜感激!谢谢。

【问题讨论】:

  • 有一个使用共享内存的选项,但实施起来很困难,并不适合所有应用程序。能否请您说一下您正在研究的方法是什么?
  • 我正在对 GPU 上的算法进行一些研究。我正在研究搜索/排序算法并尝试优化当前的前缀总和部分(以避免使用原子)。我想要完成的本质上是一个全局内存转置,以便每个块从每个其他块中获取 1 个元素。这将让我以合并模式读写,并对每个块的元素执行前缀求和。

标签: c++ arrays cuda gpgpu nvidia


【解决方案1】:

事实证明,我的算法本身必须重新设计,因为无法避免使用上述方法对非合并操作造成的性能影响。相反,我能够合并每个块上的值并使用更少的全局内存。

作为旁注,我对合并操作与非合并操作进行了一些实验,以确定它会导致多少减速。事实证明,非合并读取比合并慢约 10 倍,而非合并写入慢约 15 倍。所以我猜非合并读取是两害相权取其轻...

【讨论】:

    【解决方案2】:

    在这种情况下,在每个访问模式之间进行转置操作以将数据置于最佳顺序是值得的。转置本身可以被写入使用 SMEM,因此它的读取和写入是合并的。

    见:http://www.nvidia.com/content/nvision2008/tech_presentations/Game_Developer_Track/NVISION08-Image_Processing_and_Video_with_CUDA.pdf

    或者(克里斯蒂安在他的评论中提到)如果你能够让你的次优传递做一些类似于 SMEM 转置的事情作为它的第一步,你可以跳过完整的转置,只使用它的概念来优化它.

    【讨论】:

    • 我看到了转置如何允许合并块内操作,但是转置一个每个块有 1 行并且需要 1 列的矩阵怎么样?
    • @Nisrak:你不会那样做:你将二维矩阵分解为 NxN 个子矩阵,其中 N 是 32 的倍数(或任何你需要的最大合并),而不是打破它到行或列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    相关资源
    最近更新 更多