【问题标题】:Is private memory slower than local memory?私有内存比本地内存慢吗?
【发布时间】:2012-04-10 18:26:36
【问题描述】:

我正在研究一个内核,它每个线程都有很多全局内存访问,所以我将它们复制到本地内存,这样可以提高 40% 的速度。

我想要更快的速度,所以从本地复制到私有会降低性能

那么我认为我们不能使用太多可能会降低性能的私有内存是否正确?

【问题讨论】:

  • 一个最小的可运行示例和确切的平台规格会很棒:-)

标签: opencl


【解决方案1】:

Ashwin 的回答方向正确,但有点误导。

OpenCL 将变量的地址空间从物理存储中抽象出来,两者之间不一定存在 1:1 的映射关系。

考虑在 __private 地址空间中声明的 OpenCL 变量,默认情况下,函数内部包含自动非指针变量。 NVidia GPU 实现会尽可能将这些物理分配到寄存器中,只有在寄存器容量不足时才会溢出到物理片外内存。这种特殊的片外内存称为“CUDA 本地”内存,具有与为 __global 变量分配的内存相似的性能特征,这解释了由于寄存器溢出导致的性能损失。在这个实现中没有“私有内存”这样的物理东西,只有一个“私有地址空间”,可以在片内或片外分配。

性能损失并不是使用私有地址空间(或“私有内存”)的直接后果,私有地址空间通常分配在高性能内存中。这是因为,在这种实现下,变量太大而无法分配到高性能寄存器上,因此被“溢出”到了片外内存。

【讨论】:

    【解决方案2】:

    (我知道这是一个老问题,但给出的答案不是很准确,而且我在 Google 搜索期间在其他地方看到了相互矛盾的答案。)

    根据“Heterogeneous Computing with OpenCL”(OpenCL 1.2 修订版):

    私人记忆是单个工作项独有的记忆。局部变量 和非指针内核参数默认是私有的。在实践中,这些变量 通常映射到寄存器,尽管私有数组和任何溢出的 寄存器通常映射到片外(即长延迟)内存。

    所以,如果你使用大量私有内存,或者在私有内存中使用数组,是的,它可能会比本地内存慢。

    【讨论】:

      【解决方案3】:

      在(类似 GPU 的)OpenCL 设备中,本地内存位于芯片上并靠近处理元件 (PE)。它可能与访问 L1 缓存一样快。每个线程的私有内存实际上是从片外全局内存中分配的。这离PE很远,可能会有数百个时钟周期的延迟,从而降低读写性能。

      【讨论】:

      • 如果假设让我们像一个线程一样使用全局缓冲区值两次,而不是最初将该值保留在私有(寄存器)中会减少一次全局访问,从而提高性能。从这个意义上说,我很困惑。等待您的重播。
      • Megharaj:请注意,私有内存与寄存器不同。虽然,如果存在寄存器溢出,则可能会使用私有内存。
      • 非常感谢您的回答(danyavadagalu)。 “这与 PE 相差甚远,可能会有数百个时钟周期的延迟,从而降低读写性能。”为什么它会在下面的这种情况下提供性能“如果假设让我们像一个线程一样使用全局缓冲区值两次,而不是最初将该值保留在私有内存中会减少一次全局访问,从而提供性能”。那么我们必须在多大程度上使用私有内存。谢谢。
      • “本地内存在芯片上,靠近处理元件 (PE)。它可能和访问 L1 缓存一样快”非常感谢这个,这是有道理的,我会调查一下.再次感谢:)
      • 抱歉再次中断,我写了一个比 NVIDIA 更快的中值滤波器案例,在我的程序中,我从全局内存复制到本地内存(有效:))我不想更改本地缓冲区值所以我复制到私有内存并执行操作提供了性能。但是只使用本地内存而不复制到私有会降低性能。但是如果通过从本地复制到私有内存来执行,则性能会很好。
      【解决方案4】:

      James Beilby 的回答是正确的方向,但有点偏题:

      根据实现,它可能更快或更慢,因为 opencl 不会强制提供商使用片上或片外存储器,但 AMD 在价格/性能方面非常擅长 OpenCL,所以我将给出一些关于它。

      AMD 实现中的私有内存速度最快(延迟最短,带宽最高,例如主流 GPU 的 22 TB/s)。

      在附录-d中:

      http://developer.amd.com/wordpress/media/2013/07/AMD_Accelerated_Parallel_Processing_OpenCL_Programming_Guide-rev-2.7.pdf

      你可以看到 register 文件、LDSconstant cacheglobal 它们用于不同的命名空间当自己有足够的空间时。例如,寄存器文件有 22 TB/s,每个计算单元只有大约 300kB。这比用于 __local 内存空间的 LDS 具有更少的延迟和更多的带宽。总 LDS 大小甚至小于(每个计算单元)。

      如果从本地到私有没有好处,您应该将本地线程组大小从 256 减少到 64,例如。所以每个线程可以使用更多的私有寄存器。

      所以对于这个示例 AMD gpu,本地内存比全局内存快 15 倍,私有内存比本地内存快 5 倍。如果它不适合私有内存,它会溢出到全局内存,因此只有 L1-L2 缓存可以在这里提供帮助。如果数据没有被大量重复使用,那么在这里使用私有寄存器没有意义。如果只使用一次,只需从全局流式传输到全局即可。

      对于某些智能手机或 cpu,使用私有寄存器可能非常糟糕,因为它们可以映射到其他东西。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-06
        • 2012-07-25
        • 1970-01-01
        • 1970-01-01
        • 2014-07-07
        • 1970-01-01
        • 2019-11-24
        • 2012-03-09
        相关资源
        最近更新 更多