在Beignet 的优化指南中,针对英特尔 GPU 的 OpenCL 开源实现
工作组大小应大于 16 并且是 16 的倍数。
由于 Gen 上两个可能的 SIMD 通道是 8 或 16。为了不浪费 SIMD 通道,我们需要遵循此规则。
在Intel Processor Graphics Gen7.5的计算架构中也提到:
对于基于 Gen7.5 的产品,每个 EU 有 7 个线程,总共 28 KB 的通用寄存器文件 (GRF)。
...
在 Gen7.5 计算架构上,大多数 SPMD 编程模型采用这种风格的代码生成和 EU 处理器执行。实际上,每个SPMD 内核实例似乎都在其自己的 SIMD 通道内连续且独立地执行。
实际上,每个线程同时执行一个 SIMD-Width 数量的内核实例。因此,对于计算 内核的 SIMD-16 编译,SIMD-16 x 7 线程 = 112 个内核实例 可以在单个 EU 上同时执行。同样,对于 SIMD-32 x 7 线程 = 224 个内核实例在单个 EU 上同时执行。
如果我理解正确,SIMD-16 x 7 threads = 112 kernel instances
以 为例,为了在一个 EU 上运行 224 个线程,工作组大小需要为 16。然后 OpenCL 编译器会将 16 个内核实例折叠成一个 16 通道 SIMD 线程,并执行此操作在 7 个工作组上运行 7 次,然后在一个 EU 上运行它们?
问题1:直到这里我是正确的吗?
然而OpenCL 规范也提供向量数据类型。因此,通过传统的 SIMD 编程(如在 NEON 和 SSE 中)充分利用欧盟的 SIMD-16 计算资源是可行的。
问题 2:如果是这种情况,使用 vector-16 数据类型已经明确使用 SIMD-16 资源,因此消除了 at-least-16-item-per-work-group 限制。是这样吗?
问题3:如果以上都成立,那么这两种方法如何相互比较:1) OpenCL编译器将112个线程折叠成7个SIMD-16线程;2) 7 个本机线程被编码为明确使用向量 16 数据类型和 SIMD-16 操作?