gl_SubgroupSize は定数ではない。ほとんどの GPU ではドライバーが
パイプラインごとに選び、同じデバイス上でもシェーダーステージ間で
異なり得る。「subgroup = warp = 32」と仮定したコードは AMD
(wave64)、Intel(SIMD8/16/32)、サブグループを再パックする
あらゆるドライバーで壊れる。VK_EXT_subgroup_size_control(1.3 で
コア化)は2つのものを与える。ランタイムでの実際のサイズと、
それを固定する機能だ。
実際のサイズを読み取る
query.comp
#extension GL_KHR_shader_subgroup_basic : require
// これらはコンパイル時ではなくランタイムの値だ:
int sz = gl_SubgroupSize; // サブグループあたりの実際のレーン数
int lid = gl_SubgroupInvocationID; // レーンインデックス 0..sz-1
bool first = gl_SubgroupElect(); // 「自分はレーン 0 か?」NVIDIA では sz は32、AMD では32または64(wave64 モード)、Intel
ではパイプラインのレジスタ圧力に応じて8/16/32だ。常にランタイム値を
使うこと。32 は絶対に使わない。
サイズの固定
pin.cpp
// VkPipelineShaderStageRequiredSubgroupSizeCreateInfo は
// シェーダーステージにチェインする:
vk::PipelineShaderStageRequiredSubgroupSizeCreateInfo req{};
req.requiredSubgroupSize = 64; // AMD で wave64 を強制 — あるいは 32、16、8
vk::PipelineShaderStageCreateInfo st{};
st.pNext = &req;
st.stage = vk::ShaderStageFlagBits::eCompute;
// … モジュール、エントリーポイント …
// 許可サイズは VkPhysicalDeviceSubgroupSizeControlProperties::
// minSubgroupSize … maxSubgroupSize + requiredSubgroupSizeStages から
サイズの固定は、アルゴリズムが特定の幅向けに調整されているときに 重要だ。例えば、32レーンシャッフル向けに書かれたスキャンカーネルは、 コードが32を仮定していると wave64 で正しく動くが遅くなる。
読み取りと固定の使い分け
cases.txt
読み取りのみ(ほとんどのシェーダー):gl_SubgroupSize /
SubgroupInvocationID を使い、サイズ非依存の
コードを書く — ドライバーがパイプラインごとに
効率的な幅を選ぶ
固定(調整済みカーネル): wavefront スキャン/リダクションカーネルで
サブグループが倍になるとスクラッチメモリに
爆発する場合 — requiredSubgroupSize を固定
固定(移植性): 全プラットフォームで*最小*サイズを強制し、
動作を統一する実践的なルール
VkPhysicalDeviceSubgroupSizeControlProperties:: requiredSubgroupSizeStagesを確認する。全ドライバーで全ステージが 固定を受け付けるわけではない。requiredSubgroupSizeにはsubgroupSizeControlフィーチャーと pNext 構造体が必要だ。これは要求ではなく制約だ。ドライバーが 対応できない場合、パイプライン生成は失敗する。subgroupSize(VkPhysicalDeviceSubgroupPropertiesから)は デフォルトサイズだ。固定しない限り実際のサイズはパイプライン ごとに異なり得る。シェーダー内のgl_SubgroupSizeが真実だ。fullSubgroups(VK_EXT_shader_subgroup_ballot)との相互作用: 固定サイズはディスパッチ範囲内で全サブグループが満員であることを 保証する。部分的な末尾サブグループを扱う必要がない。- 協調行列(
VK_KHR_cooperative_matrix)はgl_ScopeSubgroupを使う。 行列タイル演算はサブグループサイズに暗黙に依存する。カーネルが 16×16タイルをハードコードしているなら固定する。
この記事が役に立った場合は、TechOverflow での新しい記事の調査と公開を支援するため、「Buy Me a Coffee」でのご支援、または PayPal 経由でのご寄付をご検討ください