【问题标题】:CUDA - Allocate constant/texture memory from the GPUCUDA - 从 GPU 分配常量/纹理内存
【发布时间】:2013-01-11 16:24:54
【问题描述】:

我应该在 CUDA 中编写一个代码,该代码在递归循环中计算一个数组。有可能在它之前预先计算这个递归循环的一些中间步骤,即分配一些常量数组和标量,这将避免循环中的一些计算。

第一个想法是将常量数组存储在全局内存中,而每次从 CPU 向 GPU 传递标量参数(此处建议:CUDA and shared variables among different global functions)。

我想尝试使用 GPU 常量内存,因为它应该更快。但是,我发现的几个示例代码说明了如何从主机分配常量内存。是否可以从 GPU 分配一些常量内存,即在那里计算它的值(就像我们对全局内存所做的那样)?您能否提供一个示例代码?

编辑:因为我可以分配很多常量数组,所以在这种情况下使用纹理内存可能会更好。是否有一些关于如何从 GPU 分配内存的示例代码?

【问题讨论】:

  • 纹理和常量内存空间对于GPU都是只读的,其中的数据只能从CPU初始化
  • @EricShiyinKang 谢谢。您如何看待第一个答案中的建议?

标签: memory-management cuda constants


【解决方案1】:

回答您的第一个问题:'是否可以从 GPU 分配一些常量内存'。简短的回答是肯定的,正如其他人回答的那样,将数据从设备复制到设备常量内存。

从这里开始,您需要考虑访问模式和问题所需的数据量。

对于常量内存,可用内存量为 65536 字节,如果一个 warp 中的所有线程同时访问同一元素,则广播数据。但是,64KB 的内存是不够的。

纹理内存具有过滤和缓存的二维空间局部性等特殊功能。因此,将纹理内存用于 3x3 窗口中的典型过滤器是典型的使用案例。

最后,如果您需要更新数据并在某些内核中使用它们,您可以选择使用全局内存。此外,您可以使用表面内存(CUDA C Programming Guire,第 3.2.10.2 章)作为读/写纹理内存。

由于您正处于我应该在 CUDA 中编写代码以在递归循环中计算数组',因此您应该首先尝试全局内存以获得未来改进的基础。当您的内核工作时,您将看到可以以不同的方式重新安排或分配哪些访问,以获得 GPU 内存的最大性能。

最后要注意的是,新的 Fermi 和 Kepler 架构已经为全局内存访问合并了 L1 和 L2 缓存层次结构,这可以缓解随机访问模式,甚至优于纹理内存,因为 L1/L2 缓存的数量更大。

最后,您可以在 CUDA SDK 中找到大量示例代码。

【讨论】:

  • 谢谢。这是我需要知道的。
【解决方案2】:

正如您所读到的here,如果您使用cudaMemcpyToSymbolcudaMemcpyDeviceToDevice 标志,那么应该可以将数据从gpu 直接复制到常量内存。 但是不可能像编辑全局内存那样编辑常量内存的日期。您只能从中读取。

【讨论】:

    【解决方案3】:

    可以从主机读取和写入常量内存。您只能从设备中读取常量内存。

    【讨论】:

    • 这很糟糕。因此,我应该在 GPU 上计算常量数组(计算起来非常昂贵),将数据传输到 CPU,然后再次将其传输到 GPU 常量内存?
    • 是的,你是对的。或者您可以让数据保留在全局内存中,并依靠 GPU 缓存为您缓存数据。如果你有一个带缓存的 GPU,则后者是正确的。
    • 是的,幸运的是我有,但我希望有可能使我的代码更快。现在我正在尝试实现另一个答案所说的内容。
    猜你喜欢
    • 2012-06-30
    • 1970-01-01
    • 2012-01-08
    • 2012-07-13
    • 2011-10-16
    • 2010-09-21
    • 2011-10-02
    • 2012-01-31
    • 2021-04-03
    相关资源
    最近更新 更多