Concurrency 是否可以保证WaveFront(OpenCL)中的所有线程始终同步?
众所周知,有扭曲(在CUDA中)和波前(在OpenCL中):Concurrency 是否可以保证WaveFront(OpenCL)中的所有线程始终同步?,concurrency,opencl,gpgpu,amd,simd,Concurrency,Opencl,Gpgpu,Amd,Simd,众所周知,有扭曲(在CUDA中)和波前(在OpenCL中): CUDA中的扭曲: 4.1。SIMT体系结构 扭曲一次执行一条公共指令,因此效率最高 当一个扭曲的所有32个线程都同意执行时实现 路径如果扭曲的线程通过依赖于数据的条件 分支时,扭曲会连续执行每个分支路径,禁用 不在该路径上的线程,并且当所有路径完成时 线程会聚回相同的执行路径。分支发散 仅在扭曲内发生不同的扭曲独立执行 不管它们是执行公共代码还是不相交代码 路径 SIMT体系结构类似于SIMD(单指令、多指令) 数据)单个指
- CUDA中的扭曲:
- OpenCL中的波前:
即我们知道:
- WARP(CUDA)中的线程是SIMT线程,每次总是执行相同的指令,并且总是保持同步,即WARP的线程与(CPU上的)相同
- 波阵面(OpenCL)中的线程是始终并行执行的线程,但不一定所有线程都执行完全相同的指令,也不一定所有线程都同步
结论:
- (第45页)第2章GCN设备的OpenCL性能和优化
- (第81页)第3章常青和北方岛屿设备的OpenCL性能和优化
首先,您可以查询一些值:
CL_DEVICE_WAVEFRONT_WIDTH_AMD
CL_DEVICE_SIMD_WIDTH_AMD
CL_DEVICE_WARP_SIZE_NV
CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE
但据我所知,只有东道主一方
假设这些查询返回了64
,您的问题重视线程的隐式同步
如果有人选择本地范围=4怎么办
由于opencl从开发人员那里提取了硬件时钟,所以在运行时,您无法从内核执行中知道实际的SIMD或波前大小
例如,AMD NCU有64个着色器,但在同一计算单元内有16个宽SIMD、8个宽SIMD、4个宽SIMD、2个宽SIMD,甚至两个标量单元
4个本地线程可以在两个标量和一个2宽单元或任何其他SIMD组合上共享。内核代码不可能知道这一点。即使它知道某种计算方法,您也无法知道在运行时在随机计算单元(64个着色器)中的下一个内核执行(甚至下一个工作组)将使用哪个SIMD组合。
或者,GCN CU(其中包含4x16个SIMD)可以为每个SIMD分配1个线程,使所有4个线程完全独立。如果它们都在同一个SIMD中,那么你就幸运了。无法保证知道“在”内核执行之前。即使在您知道之后,下一个内核可能会有所不同,因为无法保证选择相同的SIMD分配(后台内核、3d可视化软件,甚至操作系统都可能在管道中放置气泡)
无法保证在内核执行之前命令/提示/查询N个线程以相同的SIMD或相同的WARP运行。然后在内核中,没有像get_global_id(0)那样的命令来获取线程的波前索引。然后在内核之后,您不能依赖数组结果,因为下一次内核执行可能不会对完全相同的项使用相同的SIMD。即使是来自其他波前的一些项目也可以与来自当前波前的项目交换,只是为了通过驱动程序或硬件进行优化(nvidia最近推出了负载均衡器,并且可能正在这样做,amd的NCU将来也可能会使用类似的东西)
即使您在硬件和驱动程序上猜测SIMD上线程的正确组合,在另一台计算机上也可能完全不同
如果从性能角度考虑,您可以尝试:
- 零