在optimization guide of Beignet, an open source implementation of OpenCL targeting Intel GPUs
中工作组大小应大于16且是16的倍数。
Gen上的两个可能的SIMD通道是8或16.不浪费SIMD 车道,我们需要遵循这条规则。
Compute Architecture of Intel Processor Graphics Gen7.5中也提到了
对于基于Gen7.5的产品,每个EU有七个线程,总共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 spec也提供了矢量数据类型。因此,通过传统的SIMD编程(如在NEON和SSE中)充分利用EU中的SIMD-16计算资源是可行的。
问题2:如果是这种情况,使用vector-16数据类型已经明确使用了SIMD-16资源,因此删除了至少16项的每项工作组限制。是这种情况吗?
问题3:如果以上都是真的,那么两种方法如何相互比较: 1)通过OpenCL将112个线程折叠成7个SIMD-16线程编译器; 2) 7个本机线程编码为明确使用vector-16数据类型和SIMD-16操作?
答案 0 :(得分:1)
几乎。您假设每个工作组有一个线程(在此上下文中的N.B.线程是CUDA称之为“wave”。在Intel GPU中,工作项是GPU线程的SIMD通道)。没有子组,就没有办法强制工作组大小完全是一个线程。例如,如果您选择WG大小为16,编译器仍然可以自由编译SIMD8并将其分布在两个SIMD8线程中。请记住,编译器在知道WG大小之前选择SIMD宽度(clCompileProgram
在clEnqueueNDRange
之前)。 subgroups extension可能允许您强制使用SIMD宽度,但绝对不能在GEN7.5上实现。
OpenCL矢量类型是在已经自动发生的隐式矢量化之上的可选显式矢量化步骤。您是否以float16
为例。每个工作项每个处理16个浮点数,但编译器仍然至少编译SIMD8。因此,每个GPU线程将处理(8 * 16)浮点数(尽管并行)。这可能有点矫枉过正。理想情况下,我们不希望使用显式OpenCL向量类型显式地向量化我们的CL。但是,如果内核没有做足够的工作(内核太短可能会很糟糕),它会有所帮助。在某处,它说float4是一个很好的经验法则。
我认为你的意思是112个工作项目?通过本机线程你的意思是CPU线程或GPU线程?