subgroups
subgroups
称为子组
,Vulkan 规范将其定义为:
一组可以高效相互同步和共享数据的着色器调用。在计算着色器中,本地工作组是子组的超集。
对于许多驱动实现,subgroup
是同时运行同一指令的调用组。subgroup
允许着色器以比单个工作组更精细的粒度进行工作。
资源
关于subgroup
更详细的信息,请参阅一篇很棒的 Khronos 博客文章,以及 2018 年 Vulkan 开发者大会的PPT和视频),GLSL 对subgroup
的支持在 GL_KHR_shader_subgroup 扩展中可以找到。
subgroup
大小
subgroup
的大小是驱动动态调整的,某些驱动实现执行着色器时可能会为不同的subgroup
分派不同的subgroup
大小。因此,他们可以隐式地将一个大型subgroup
拆分为较小的subgroup
,或者将一个小型subgroup
表示为较大的subgroup
。
VK_EXT_subgroup_size_control
在 Vulkan 1.3 中提升为核 心扩展
创建此扩展的原因是某些驱动实现具有多个大小,而 Vulkan 最初只公开了单个subgroup
大小。
例如,如果一个驱动实现同时支持4
和 16
大小的subgroup
,以前只需要公开一个 size,但现在可以同时公开两个 size。这意味着允许应用程序以更精细的粒度控制多个subgroup
的硬件。如果设备不支持该扩展,则意味着只公开支持一个subgroup
的大小。
检查是否支持
在 Vulkan 1.1 中,subgroup
所有的信息都可以在VkPhysicalDeviceSubgroupProperties
中查到。
VkPhysicalDeviceSubgroupProperties subgroupProperties;
VkPhysicalDeviceProperties2KHR deviceProperties2;
deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
deviceProperties2.pNext = &subgroupProperties;
vkGetPhysicalDeviceProperties2(physicalDevice, &deviceProperties2);
// Example of checking if supported in fragment shader
if ((subgroupProperties.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) != 0) {
// fragment shaders supported
}
// Example of checking if ballot is supported
if ((subgroupProperties.supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT) != 0) {
// ballot subgroup operations supported
}
保证支持
Vulkan Spec强调驱动实现必须支持的管线阶段:
如果物理设备支持VK_QUEUE_COMPUTE_BIT队列,则 supportedStages 将设置 VK_SHADER_STAGE_COMPUTE_BIT 位。
Vulkan Spec强调驱动实现必须支持的操作:
如果物理设备支持 VK_QUEUE_GRAPHICS_BIT 或 VK_QUEUE_COMPUTE_BIT队列,则supportedOperations 将设置 VK_SUBGROUP_FEATURE_BASIC_BIT 位。
VK_KHR_shader_subgroup_extended_types
在 Vulkan 1.2 中提升为核心扩展GLSL_EXT_shader_subgroup_extended_types
此扩展允许在 subgroup
范围的group操作使用 8 位整数、16 位整数、64 位整数、16 位浮点和这些类型的向量(前提是驱动实现支持这些类型)。
例如,如果驱动实现支持 8 位整数,那么应用程序可以使用 GLSL的 genI8Type subgroupAdd(genI8Type value);
调用,该调用将在 SPIR-V 中映射到OpGroupNonUniformFAdd
。
VK_EXT_shader_subgroup_ballot 和 VK_EXT_shader_subgroup_vote
VK_EXT_shader_subgroup_ballot
和VK_EXT_shader_subgroup_vote
是 Vulkan 最开始公开的 subgroup
扩展。如果应用程序使用的是 Vulkan 1.1 或更高版本,则无需使用这些扩展,而应使用核心 API 来查询是否支持 subgroup
。