在Beignet的优化指南中,这是一个针对Intel GPU的开源OpenCL实现(链接)。
工作组大小应大于16且为16的倍数。
Gen上有两个可能的SIMD通道,分别为8或16。为了不浪费SIMD通道,我们需要遵循这个规则。
在Intel处理器图形Gen7.5的计算架构中也提到了这一点:
对于基于Gen7.5的产品,每个EU有七个线程,总共28 Kbytes的通用寄存器文件(GRF)。在Gen7.5计算架构上,大多数SPMD编程模型采用这种样式的代码生成和EU处理器执行。实际上,每个线程在其自己的SIMD lane中同时执行一定数量的kernel instances。因此,对于一个SIMD-16编译的计算内核来说,可能会在单个EU上并行地执行SIMD-16 x 7 threads = 112个内核实例。同样,对于SIMD-32 x 7 threads = 224的情况,也会在单个EU上并行地执行224个内核实例。如果我理解得正确,使用“SIMD-16 x 7 threads = 112 kernel instances”作为例子,在一个EU上运行224个线程,工作组大小需要为16。然后,OpenCL编译器将16个内核实例折叠成一个16个lane的SIMD线程,并在7个工作组上重复这个过程,然后在一个单独的EU上运行它们。问题1:我现在的理解是正确的吗?
然而,OpenCL规范 也提供了向量数据类型。因此,通过常规的SIMD编程(如NEON和SSE),可以充分利用EU中的SIMD-16计算资源。
问题2:如果是这样,使用向量-16数据类型已经明确地利用了SIMD-16资源,因此消除了每个工作组至少16个项目的限制。是这样吗?
问题3:如果上述都是真的,那么这两种方法相互比较如何:1)由OpenCL编译器将112个线程合并为7个SIMD-16线程;2)7个本地线程编码以明确使用向量-16数据类型和SIMD-16操作?