Start · Sprachen · JavaScript · Referenz · GPUAdapterInfo.subgroupMinSize

GPUAdapterInfo.subgroupMinSize

Eigenschaft

Schreibgeschützte Zahl, die die kleinste Subgruppen-Größe angibt, die der <code>GPUAdapter</code> in Compute-Shadern verwenden kann.

seit JavaScript WebGPU; Chromium-basierte Browser (ca. Chrome 134+ Kategorie: webapi

Signatur

GPUAdapterInfo.subgroupMinSize

Beschreibung

Die schreibgeschützte Eigenschaft subgroupMinSize des Interfaces GPUAdapterInfo gibt die minimal unterstützte Subgruppen-Größe des physischen Grafikadapters zurück. Eine Subgruppe (auf NVIDIA-Hardware „Warp“, auf AMD „Wavefront“, unter Vulkan „Subgroup“) ist eine Gruppe von Shader-Aufrufen, die gleichzeitig im Gleichschritt laufen und über schnelle Subgruppen-Operationen wie subgroupAdd(), subgroupBroadcast() oder subgroupBallot() Daten austauschen können.

Zusammen mit subgroupMaxSize legt der Wert den Bereich fest, in dem die tatsächliche Subgruppen-Größe liegt, die ein Shader zur Laufzeit über das WGSL-Built-in subgroup_size erhält. Die konkrete Größe kann je nach Pipeline, Treiber und Shader unterschiedlich ausfallen. Deshalb sollte man sich im Shader-Code nicht auf einen festen Wert verlassen, sondern den Bereich bei der Planung berücksichtigen.

Man nutzt den Wert vor allem, um Workgroup-Größen und Algorithmen wie Reduktionen, Präfixsummen oder Sortierverfahren passend zur Hardware zu wählen. Beispiele dafür sind eine Workgroup-Größe, die ein Vielfaches der Subgruppen-Größe ist, oder die Anzahl der Shared-Memory-Slots für Teilergebnisse pro Subgruppe. Man erreicht das GPUAdapterInfo-Objekt über GPUAdapter.info oder, nach dem Anlegen des Geräts, über GPUDevice.adapterInfo.

Subgruppen-Operationen selbst funktionieren nur, wenn beim Anfordern des Geräts das Feature "subgroups" angegeben wird und der WGSL-Code die Direktive enable subgroups; enthält.

Rückgabewert

Typ
number
Beschreibung
Ganzzahl (unsigned long), die kleinste mögliche Subgruppen-Größe des Adapters. In der Praxis ist sie eine Zweierpotenz, typischerweise 4, 8, 16, 32 oder 64. Sie ist immer kleiner oder gleich subgroupMaxSize.

Beispiele

Subgruppen-Bereich des Adapters auslesen

const adapter = await navigator.gpu?.requestAdapter();
if (!adapter) {
  throw new Error('WebGPU wird nicht unterstützt.');
}

const { vendor, architecture, subgroupMinSize, subgroupMaxSize } = adapter.info;
console.log(`${vendor} (${architecture})`);
console.log(`Subgruppen-Größe: ${subgroupMinSize} bis ${subgroupMaxSize}`);
nvidia (ampere) Subgruppen-Größe: 32 bis 32

Gerät mit dem Feature "subgroups" anfordern und Werte über device.adapterInfo prüfen

const adapter = await navigator.gpu.requestAdapter();

const requiredFeatures = adapter.features.has('subgroups') ? ['subgroups'] : [];
const device = await adapter.requestDevice({ requiredFeatures });

if (device.features.has('subgroups')) {
  const info = device.adapterInfo;
  console.log('Subgruppen aktiv, Minimum:', info.subgroupMinSize);
} else {
  console.log('Keine Subgruppen-Unterstützung – Fallback über Shared Memory.');
}
Subgruppen aktiv, Minimum: 32

Workgroup-Größe und Shared-Memory-Puffer für eine Reduktion wählen

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice({ requiredFeatures: ['subgroups'] });
const { subgroupMinSize } = adapter.info;

const WORKGROUP_SIZE = 256;
// Die meisten Subgruppen entstehen bei der kleinsten Subgruppen-Größe
const maxSubgroups = Math.ceil(WORKGROUP_SIZE / subgroupMinSize);

const code = /* wgsl */ `
  enable subgroups;

  @group(0) @binding(0) var<storage, read> input: array<f32>;
  @group(0) @binding(1) var<storage, read_write> output: array<f32>;

  var<workgroup> partial: array<f32, ${maxSubgroups}>;

  @compute @workgroup_size(${WORKGROUP_SIZE})
  fn main(@builtin(global_invocation_id) gid: vec3u,
          @builtin(local_invocation_index) lid: u32,
          @builtin(workgroup_id) wid: vec3u,
          @builtin(subgroup_size) sgSize: u32,
          @builtin(subgroup_invocation_id) sgId: u32) {
    let sum = subgroupAdd(input[gid.x]);
    if (sgId == 0u) { partial[lid / sgSize] = sum; }
    workgroupBarrier();
    if (lid == 0u) {
      var total = 0.0;
      for (var i = 0u; i < ${WORKGROUP_SIZE}u / sgSize; i++) { total += partial[i]; }
      output[wid.x] = total;
    }
  }
`;

const module = device.createShaderModule({ code });
console.log(`Puffer für ${maxSubgroups} Teilsummen reserviert.`);
Puffer für 8 Teilsummen reserviert.

// Wichtig · Fallstricke

  • Kein fester Wert: Die tatsächliche Subgruppen-Größe eines Shader-Aufrufs liegt irgendwo zwischen subgroupMinSize und subgroupMaxSize. Auf Intel- und manchen Mobil-GPUs kann sie je nach Pipeline wechseln, zum Beispiel zwischen 8, 16 und 32. Im Shader liest man sie über @builtin(subgroup_size) aus. Shared-Memory-Puffer bemisst man nach subgroupMinSize, weil bei der kleinsten Größe die meisten Subgruppen entstehen.
  • Feature nötig: Die Eigenschaft kann man auch ohne das Feature "subgroups" lesen. Subgruppen-Built-ins und -Funktionen stehen im Shader aber nur zur Verfügung, wenn das Feature in requestDevice() angefordert wurde und der WGSL-Code enable subgroups; enthält. Sonst schlägt die Kompilierung fehl.
  • Kompatibilität: WebGPU und besonders die Subgruppen-Eigenschaften gibt es derzeit vor allem in Chromium-basierten Browsern. Firefox und Safari unterstützen WebGPU nur teilweise oder hinter Flags. Ältere Browser liefern undefined. Deshalb sollte man die Eigenschaft vorher prüfen, etwa mit adapter.info.subgroupMinSize ?? 0.
  • Datenschutz: Hardware-Details in GPUAdapterInfo können sich zum Fingerprinting eignen. Browser dürfen die Werte deshalb vereinheitlichen oder vergröbern.
  • Die Eigenschaft ist nur in einem sicheren Kontext (HTTPS) verfügbar.