总结各GPU的OpenCL子组洗牌支持情况

目录

  • Nvidia
  • Intel
  • [AMD ROCm](#AMD ROCm)
  • [AMD PAL/HSAIL](#AMD PAL/HSAIL)
  • [Qualcommon Adreno](#Qualcommon Adreno)
  • CLVK
  • 参见

子组(Sub-group)自 OpenCL 2.0 正式引入,是工作组(Work-group)内部更小的执行单位,通常直接映射到 GPU 的 SIMD/SIMT 执行单元(如 Nvidia Warp 和 AMD Wavefront),具有更好的数据共享与同步能力。

OpenCL 2.0 通过扩展cl_khr_subgroups提供一些基础子组操作支持,包括获取子组 ID、组内 ID 等基本功能,组内断言(any/all)、广播(broadcast)、归约(reduce)、扫描(scan)等基本操作,同时允许一些可选扩展支持更丰富的子组操作(比如洗牌(shuffle)、投票(ballot)等)。其中子组内洗牌用于直接交换子组内寄存器值而不借助全局或本地内存(类比 CUDA 束内洗牌),经常用于一些算法优化,是比较有用的子组函数,但是大多数 GPU 都不支持官方的cl_khr_subgroup_shuffle扩展。当然一些厂商也可以通过厂商扩展、内联汇编(Inline Assembly)、内置函数(Intrinsics/Builtins)等途径支持子组洗牌。

Nvidia

通过内置函数__nvvm_shfl_<mode>_<type>(sm_70 以前)、__nvvm_shfl_sync_<mode>_<type>(sm_70+, ptx60+[[1]](#[1]))支持。CUDA 中的线程束洗牌原语也是通过这些内置函数实现的。

内置函数 功能
gentype __nvvm_shfl_<mode>_<type>(gentype val, int offset, int clamp) 按照<mode>定义规则将offset处车道的val传递到本车道,对clamp内源车道有效
gentype __nvvm_shfl_sync_<mode>_<type>(uint mask, gentype val, int offset, int clamp) 按照<mode>定义规则将offset处车道的val传递到本车道,并按照mask同步线程束,对clamp内源车道有效

其中<type>可取i32f32,对应gentypeintfloat

其中<mode>取值如下:

<mode> 目的车道 对标 OpenCL 子组函数 对应 OpenCL 子组扩展
idx offset sub_group_shuffle cl_khr_subgroup_shuffle
bfly laneid ^ offset sub_group_shuffle_xor cl_khr_subgroup_shuffle
up laneid - offset sub_group_shuffle_up cl_khr_subgroup_shuffle_relative
down laneid + offset sub_group_shuffle_down cl_khr_subgroup_shuffle_relative

Nvidia 的 OpenCL 驱动支持 PTX 内联汇编,因此可直接调用shfl.<mode>.<type>shfl.sync.<mode>.<type>等汇编指令。

Intel

提供扩展cl_intel_subgroups支持多种子组洗牌操作。目前 Intel 是对 OpenCL 支持比较好的厂商,该扩展自 OpenCL 1.2 加入,并且直接实现了多种子组洗牌、投票函数。

扩展函数 功能
gentype intel_sub_group_shuffle(gentype data, uint sub_group_local_id) sub_group_local_id子组工作项的数据值传递给本子组工作项。
gentype intel_sub_group_shuffle_down(gentype curr, gentype, gentype next, uint delta) sub_group_local_id+delta作为目的子组索引。 若子组索引大于等于 0 且小于max_sub_group_size则传递curr。 若子组索引大于等于max_sub_group_size且小于max_sub_group_size * 2,则将目的子组索引减max_sub_group_size,传递next
gentype intel_sub_group_shuffle_up(gentype curr, gentype, gentype next, uint delta) sub_group_local_id-delta作为目的子组索引。 若子组索引大于等于 0 且小于max_sub_group_size则传递curr。 若子组索引大于等于负max_sub_group_size且小于 0,则将目的子组索引加max_sub_group_size,传递next
gentype intel_sub_group_shuffle_xor(gentype data, uint val) sub_group_local_id XOR val子组工作项的数据值传递给本子组工作项。

AMD ROCm

有前缀为__builtin_amdgcn_的内置函数ds_permuteds_bpermute,前者将数据从当前车道推送(Push)到目标车道,而后者从目标车道拉取(Pull)到当前车道,与 OpenCL 中的 sub_group_shuffle 定义类似。

内置函数 功能
int __builtin_amdgcn_ds_permute(int offset, int val) 将本车道的数据值传输到索引为offset的车道
int __builtin_amdgcn_ds_bpermute(int offset, int val) 将索引为offset的车道的数据值传输到本车道

另外,AMD ROCm 还提供ds_swizzle(字节单位交换)、dpp_mov(数据并行移动)等内部函数实现更丰富的子组洗牌操作。

AMD ROCm 的 OpenCL 驱动同样支持内联汇编,可以直接调用ds.permuteds.bpermute等 AMDGCN 指令。

AMD PAL/HSAIL

ROCm 不支持 Windows 集显,其默认驱动为 AMD PAL/HSAIL。AMD PAL/HSAIL 提供内置函数gentype __hsail_activelanepermute_wavewidth_<type>(gentype src, uint lid, gentype ival, bool useival)实现活跃车道交换(不同步)[[2]](#[2])。该函数将目的索引lid的车道的数据值交换到本车道。若lid非法,当useival为真时,返回ival,否则未定义。

其中<w>可取b1b32b64,表示该指令进行交换的数据宽度,对应gentypeucharuintulong

使用__hsail_activelanepermute_wavewidth_<type>时需要在代码中声明该函数,否则编译时会报错找不到符号。参见HSAFoundation/builtins[[3]](#[3])

另外,sub_group_broadcast是用该指令与__hsail_wavebarrier()实现的,因此也可用子组广播进行洗牌。

Qualcommon Adreno

提供扩展cl_qcom_subgroup_shuffle支持子组洗牌操作,允许全组洗牌、宽 4 洗牌、宽 8 洗牌。

扩展函数:

c 复制代码
<gentype> qcom_sub_group_shuffle_<op>(
            <gentype> source_value,
            uint offset,
            qcom_sub_group_shuffle_width_modes_t width,
            <gentype> default_value);

其中<gentype>可为ucharcharushortshortuintintulonglong以及float,如果启用cl_khr_fp16扩展,则也可取half

其中<op>可为updownrotate_uprotate_downxor

qcom_sub_group_shuffle_width_modes_t为枚举类型,取值如下:

子组洗牌宽度模式 含义
CLK_SUB_GROUP_SHUFFLE_WIDTH_WAVE_SIZE_QCOM 子组内所有工作项参与洗牌
CLK_SUB_GROUP_SHUFFLE_WIDTH_W4_QCOM 子组内每4个工作项之间洗牌
CLK_SUB_GROUP_SHUFFLE_WIDTH_W8_QCOM 子组内每8个工作项之间洗牌

CLVK

CLVK 是基于 Vulkan 的 OpenCL 3.0 实现,使用 clspv 编译器将 OpenCL C 源码编译为 SPIR-V 二进制格式作为 Vulkan 计算着色器使用。CLVK 支持官方 cl_khr_subgroup_shuffle 扩展。


参见

  1. https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_C.html#sub-group-functions
  2. https://reviews.llvm.org/D38090
  3. https://registry.khronos.org/OpenCL/extensions/intel/cl_intel_subgroups.html
  4. https://reviews.llvm.org/D17614
  5. https://github.com/HSAFoundation/builtins
  6. https://github.com/HSAFoundation/HLC-HSAIL-Development-LLVM/blob/hsail-review-v4/lib/Target/HSAIL/HSAILIntrinsics.td
  7. https://github.com/willhua/QualcommOpenCLSDKNote/blob/master/docs/extensions/cl_qcom_subgroup_shuffle.txt

原文连接 https://www.cnblogs.com/RainbowC0/p/19595783,未经作者许可禁止转载。


  1. 架构可通过编译参数-cl-nv-arch指定,默认与设备架构一致;ptx60 需要通过编译参数--Xclang -target-feature --Xclang +ptx60指定。 ↩︎

  2. 驱动程序中还可以看到__gcn_ds_permute_<type>__gcn_ds_bpermute_<type>__gcn_dpp_mov_<type>等内置函数,但实际编译时会报错LLVM ERROR: cannot select: intrinsic,GPU 本身是 GCN 架构,可能需要通过特定编译参数支持 GCN 扩展。 ↩︎

  3. 目前的驱动程序内有字段__hsail_activelanepermute_wavewidth,而HSAFoundation/builtins内给出的是__hsail_activelaneshuffle_wavewidth,应该有误。 ↩︎

相关推荐
70asunflower2 天前
算子开发到底在做什么?
gpu·就业·岗位
迎仔4 天前
B-基础:GPU驱动基础概念
gpu
迎仔4 天前
F-排查:GPU驱动故障排查手册
gpu·gpu驱动
迎仔4 天前
D-安装:GPU驱动安装与升级最佳实践
gpu·gpu驱动
迎仔4 天前
E-自动化:GPU驱动维护自动化
运维·gpu·gpu驱动
小白狮ww6 天前
要给 OCR 装个脑子吗?DeepSeek-OCR 2 让文档不再只是扫描
人工智能·深度学习·机器学习·ocr·cpu·gpu·deepseek
小白狮ww13 天前
Ovis-Image:卓越的图像生成模型
人工智能·深度学习·目标检测·机器学习·cpu·gpu·视觉分割模型
virtaitech14 天前
云平台一键部署【rednote-hilab/dots.ocr】多语言文档布局解析模型
人工智能·科技·ai·ocr·gpu·算力
virtaitech15 天前
如何评价趋动科技推出永久免费的OrionX社区版?
人工智能·科技·ai·免费·gpu·池化技术