OpenCL 设备的最大(理想)内存带宽是多少?
What is maximum (ideal) memory bandwidth of an OpenCL device?
我的 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
时才被视为?
内存条 quantity/width 与内存带宽有什么关系吗?在编写内核时,是否有一种方法可以推断内存条的内存性能?
内存库数量对于提示跨步访问模式性能和内存库冲突很有用。
缓存行宽度必须是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内存是由两个堆栈组成的,那么它的256GB/s.
如果您的 data-set 适合 L2 缓存,那么您希望在重复访问下获得更多带宽。
但是真正的性能(而不是纸上谈兵)可以通过一个简单的基准来衡量,该基准在两个阵列之间进行流水线内存复制。
8 个工作项的总性能取决于计算单元的能力。如果每个工作项每个时钟只允许 32 个字节,那么您可能需要更多工作项。计算单元必须有一些优化阶段,比如将相似的地址打包到每个 CU 的一个大内存访问中。因此,您甚至可以仅使用单个工作组来实现最高性能(但使用多个工作项,而不仅仅是 1 个,数量取决于每个工作项访问的对象的大小及其能力)。您可以在 array-summation 或缩减内核上对其进行基准测试。仅 1 个计算单元通常足以利用全局内存带宽,除非其单个 L2-L1 带宽低于全局内存带宽。但对于 highest-end 张卡片可能并非如此。
你的显卡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 服务器只供您使用)。
着色器带宽:
如果这些是 per-shader 限制,那么单个着色器可以使用它自己的所有 CU L1-L2 带宽,尤其是在读取时。
还说 L0-L1 缓存行大小为 128 字节,因此 1 个工作项可能正在使用该宽数据类型。
N-way-set-associative 缓存(上图中的 L1、L2)和 direct-mapped 缓存(可能是纹理缓存?)使用模映射。但是 LRU(此处为 L0)可能不需要模访问。由于您需要全局内存带宽,因此您应该查看 L2 缓存行,它是 n-way-set-associative 因此是模数。即使数据已经在 L0 中,OpenCL 规范也可能不允许您对数据进行 non-modulo-x 访问。如果数组是您需要处理的数据类型,您也不必考虑对齐问题。
如果您不想 fiddle 使用微基准测试并且不知道需要多少工作项,那么您可以在内核中使用异步工作组复制命令。异步复制实现仅使用所需数量的着色器(或根本不使用着色器?取决于硬件)。然后您可以从单个工作项快速访问本地内存。
但是,单个工作项可能需要一个展开的循环来执行流水线操作以使用其 CU 的所有带宽。仅一个 read/write 操作不会填满管道并使延迟可见(不会隐藏在其他延迟之后)。
注意:L2 时钟频率可以与主内存频率不同,而不仅仅是 1GHz。那里可能有一个 L3 缓存或其他东西来适应不同的频率。也许它的 gpu 频率像 2GHz。然后所有 L1 L0 带宽也更高,例如每个 L1-L2 通信 512 GB/s。您可能需要为此查询 CL_ DEVICE_ MAX_ CLOCK_ FREQUENCY。无论如何,只有 1 个 CU 看起来能够使用 high-end 卡的 90% 的带宽。 RX6800XT 具有 512GB/s 主内存带宽和 2GHz gpu,因此它很可能只使用 1 个 CU 来完成。
我的 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
时才被视为?
内存条 quantity/width 与内存带宽有什么关系吗?在编写内核时,是否有一种方法可以推断内存条的内存性能?
内存库数量对于提示跨步访问模式性能和内存库冲突很有用。
缓存行宽度必须是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内存是由两个堆栈组成的,那么它的256GB/s.
如果您的 data-set 适合 L2 缓存,那么您希望在重复访问下获得更多带宽。
但是真正的性能(而不是纸上谈兵)可以通过一个简单的基准来衡量,该基准在两个阵列之间进行流水线内存复制。
8 个工作项的总性能取决于计算单元的能力。如果每个工作项每个时钟只允许 32 个字节,那么您可能需要更多工作项。计算单元必须有一些优化阶段,比如将相似的地址打包到每个 CU 的一个大内存访问中。因此,您甚至可以仅使用单个工作组来实现最高性能(但使用多个工作项,而不仅仅是 1 个,数量取决于每个工作项访问的对象的大小及其能力)。您可以在 array-summation 或缩减内核上对其进行基准测试。仅 1 个计算单元通常足以利用全局内存带宽,除非其单个 L2-L1 带宽低于全局内存带宽。但对于 highest-end 张卡片可能并非如此。
你的显卡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 服务器只供您使用)。
着色器带宽:
如果这些是 per-shader 限制,那么单个着色器可以使用它自己的所有 CU L1-L2 带宽,尤其是在读取时。
还说 L0-L1 缓存行大小为 128 字节,因此 1 个工作项可能正在使用该宽数据类型。
N-way-set-associative 缓存(上图中的 L1、L2)和 direct-mapped 缓存(可能是纹理缓存?)使用模映射。但是 LRU(此处为 L0)可能不需要模访问。由于您需要全局内存带宽,因此您应该查看 L2 缓存行,它是 n-way-set-associative 因此是模数。即使数据已经在 L0 中,OpenCL 规范也可能不允许您对数据进行 non-modulo-x 访问。如果数组是您需要处理的数据类型,您也不必考虑对齐问题。
如果您不想 fiddle 使用微基准测试并且不知道需要多少工作项,那么您可以在内核中使用异步工作组复制命令。异步复制实现仅使用所需数量的着色器(或根本不使用着色器?取决于硬件)。然后您可以从单个工作项快速访问本地内存。
但是,单个工作项可能需要一个展开的循环来执行流水线操作以使用其 CU 的所有带宽。仅一个 read/write 操作不会填满管道并使延迟可见(不会隐藏在其他延迟之后)。
注意:L2 时钟频率可以与主内存频率不同,而不仅仅是 1GHz。那里可能有一个 L3 缓存或其他东西来适应不同的频率。也许它的 gpu 频率像 2GHz。然后所有 L1 L0 带宽也更高,例如每个 L1-L2 通信 512 GB/s。您可能需要为此查询 CL_ DEVICE_ MAX_ CLOCK_ FREQUENCY。无论如何,只有 1 个 CU 看起来能够使用 high-end 卡的 90% 的带宽。 RX6800XT 具有 512GB/s 主内存带宽和 2GHz gpu,因此它很可能只使用 1 个 CU 来完成。