【问题标题】:What is maximum (ideal) memory bandwidth of an OpenCL device?OpenCL 设备的最大(理想)内存带宽是多少?
【发布时间】:2022-01-27 21:04:43
【问题描述】:

我的 OpenCL 设备内存相关规范是:

Max compute units                               20
Global memory channels (AMD)                    8
Global memory banks per channel (AMD)           4
Global memory bank width (AMD)                  256 bytes
Global Memory cache line size                   64 bytes

这是否意味着要充分利用我的设备在内存方面的潜力,它需要在不同的 CU 上具有 8 个工作项,不断读取 64 字节的内存块?内存通道的排列是否允许不同的 CU 同时访问内存? 64 字节的内存读取是否始终被视为单次读取,或者仅当地址为 % 64 == 0 时才被视为?
内存条的数量/宽度是否与内存带宽有关?在编写内核时是否有办法推断内存性能?

【问题讨论】:

    标签: memory gpu opencl


    【解决方案1】:

    内存库数量有助于提示跨步访问模式性能和库冲突。

    缓存线宽度必须是 L2 和 CU(L1) 之间的 L2 缓存线。每个周期 64 字节意味着每个计算单元 64GB/s(假设每个 CU 一次只有 1 个活动缓存线和 1GHz 时钟)。每个 L1 也可以有多个,比如 4 个。)。对于 20 个计算单元,“L2 到 L1”的总带宽必须为 1.28TB/s,但它相对于全局内存的主要优势必须是获取数据的时钟周期更短。

    如果您需要使用全局内存,那么您需要接近 L2 和主内存之间的带宽限制。这与记忆通道的宽度、记忆通道的数量和频率有关。

    Gddr 通道宽度为 64 位,HBM 通道宽度为 128 位。单个 hbm v1 堆栈有 8 个通道,因此总共有 1024 位或 128 字节。每个周期 128 字节意味着每 GHz 128GB/s。更多的堆栈意味着更多的带宽。如果 8GB 内存由两个堆栈组成,那么它的 256 GB/s。

    如果您的数据集适合 L2 缓存,那么您期望在重复访问下获得更多带宽。

    但真正的性能(而不是纸面上的)可以通过在两个数组之间进行流水线内存复制的简单基准来衡量。

    8 个工作项的总性能取决于计算单元的能力。如果每个工作项每个时钟只允许 32 个字节,那么您可能需要更多工作项。计算单元必须有一些优化阶段,比如将相似的地址打包到每个 CU 访问的一个大内存中。因此,您甚至可以仅使用单个工作组来实现最大性能(但使用多个工作项,而不仅仅是 1 个,数量取决于每个工作项访问的对象的大小及其能力)。您可以在数组求和或归约内核上对此进行基准测试。通常只有 1 个计算单元足以利用全局内存带宽,除非其单个 L2-L1 带宽低于全局内存带宽。但对于最高端的卡来说可能并非如此。

    您的卡的 L2 和 L1 之间的并行度是多少?一次只有 1 条活动线路?那么你可能会重新设计分布在 8 个工作组中的 8 个工作项。

    根据 AMD 关于 rdna 的数据表,每个着色器能够在飞行中执行 10-20 个请求,因此如果 1 个 rdna 计算单元 L1-L2 通信足以使用全局内存的所有 bw,那么即使只有几个工作项单个工作组就足够了。

    L1-L2 带宽:

    它表示每个 L1 和 L2 之间有 4 条线路处于活动状态。所以每个计算单元必须有 256GB/s。在不同的 CU 上运行的 4 个工作组应该足以满足 1TB/s 的主内存。我猜 OpenCL 无法访问这些信息,并且这可能会因新卡而改变,所以最好的办法是对各种设置进行基准测试,例如从 1 个 CU 到 N CU,从 1 个工作项到 N 个工作项。在没有争用的情况下测量应该不会花费太多时间(即整个 gpu 服务器只供您使用)。

    着色器带宽:

    如果这些是每个着色器的限制,那么单个着色器可以使用它自己的所有 CU L1-L2 带宽,尤其是在读取时。

    还说 L0-L1 缓存线大小为 128 字节,因此 1 个工作项可能正在使用该宽数据类型。

    N-way-set-associative 缓存(上图中的 L1、L2)和直接映射缓存(可能是纹理缓存?)使用模映射。但是 LRU(这里是 L0)可能不需要模访问。由于您需要全局内存带宽,因此您应该查看 L2 高速缓存行,它是 n-way-set-associative 因此是模数。即使数据已经在 L0 中,OpenCL 规范也可能不允许您对数据进行非模x 访问。如果数组是您需要处理的数据类型,您也不必考虑对齐。

    如果您不想摆弄微基准测试并且不知道需要多少工作项,那么您可以在内核中使用异步工作组复制命令。异步复制实现仅使用所需数量的着色器(或根本不使用着色器?取决于硬件)。然后您可以从单个工作项快速访问本地内存。

    但是,单个工作项可能需要展开循环来执行流水线操作,以使用其 CU 的所有带宽。仅仅一次读/写操作不会填满管道并使延迟可见(不会隐藏在其他延迟之后)。

    注意:L2 时钟频率可以不同于主内存频率,而不仅仅是 1GHz。那里可能有一个 L3 缓存或其他东西来适应不同的频率。也许它的GPU频率像2GHz。然后所有的 L1 L0 带宽也更高,例如每个 L1-L2 通信 512 GB/s。您可能需要为此查询 CL_​DEVICE_​MAX_​CLOCK_​FREQUENCY。无论如何,仅仅 1 个 CU 看起来就可以使用 90% 的高端卡的带宽。 RX6800XT 拥有 512GB/s 的主内存带宽和 2GHz gpu,因此很可能只使用 1 个 CU 即可。

    【讨论】:

      猜你喜欢
      • 2020-07-24
      • 2012-09-01
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      • 2012-02-14
      • 1970-01-01
      • 2010-12-02
      相关资源
      最近更新 更多