มีอะไรใหม่ใน WebGPU (Chrome 120)

François Beaufort
François Beaufort

การรองรับค่าทศนิยม 16 บิตใน WGSL

ใน WGSL f16 ประเภทคือชุดค่าจุดลอยตัว 16 บิตในรูปแบบ IEEE-754 binary16 (ความแม่นยำครึ่งหนึ่ง) ซึ่งหมายความว่าใช้ 16 บิตเพื่อแสดงตัวเลขทศนิยม ซึ่งต่างจาก 32 บิตสำหรับเลขทศนิยมแบบความแม่นยำเดี่ยวทั่วไป (f32) ขนาดที่เล็กลงนี้อาจส่งผลให้ประสิทธิภาพดีขึ้นอย่างมาก โดยเฉพาะเมื่อประมวลผลข้อมูลจำนวนมาก

สำหรับการเปรียบเทียบ ในอุปกรณ์ Apple M1 Pro f16การติดตั้งใช้งานโมเดล Llama2 7B ที่ใช้ในการสาธิตแชท WebLLM นั้นเร็วกว่าf32การติดตั้งใช้งานอย่างเห็นได้ชัด โดยมีความเร็วในการเติมข้อความล่วงหน้าเพิ่มขึ้น 28% และความเร็วในการถอดรหัสเพิ่มขึ้น 41% ดังที่แสดงในภาพหน้าจอต่อไปนี้

ภาพหน้าจอของการสาธิตแชท WebLLM ด้วยโมเดล Llama2 7B แบบ f32 และ f16
การสาธิตแชท WebLLM ด้วยโมเดล Llama2 7B f32 (ซ้าย) และ f16 (ขวา)

GPU บางรุ่นไม่รองรับค่าทศนิยมแบบ 16 บิต เมื่อฟีเจอร์ "shader-f16" พร้อมใช้งานใน GPUAdapter คุณจะขอ GPUDevice ด้วยฟีเจอร์นี้และสร้างโมดูล Shader WGSL ที่ใช้ประโยชน์จากประเภทจุดลอยตัวแบบความแม่นยำครึ่งหนึ่ง f16 ได้ ประเภทนี้จะใช้ในโมดูล Shader WGSL ได้ก็ต่อเมื่อคุณเปิดใช้f16ส่วนขยาย WGSL ด้วย enable f16; มิฉะนั้น createShaderModule() จะสร้างข้อผิดพลาดในการตรวจสอบความถูกต้อง ดูตัวอย่างที่เล็กที่สุดต่อไปนี้และปัญหา dawn:1510

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("shader-f16")) {
  throw new Error("16-bit floating-point value support is not available");
}
// Explicitly request 16-bit floating-point value support.
const device = await adapter.requestDevice({
  requiredFeatures: ["shader-f16"],
});

const code = `
  enable f16;

  @compute @workgroup_size(1)
  fn main() {
    const c : vec3h = vec3<f16>(1.0h, 2.0h, 3.0h);
  }
`;

const shaderModule = device.createShaderModule({ code });
// Create a compute pipeline with this shader module
// and run the shader on the GPU...

คุณรองรับทั้งประเภท f16 และ f32 ในโค้ดโมดูล Shader ของ WGSL ได้ด้วย alias โดยขึ้นอยู่กับการรองรับฟีเจอร์ "shader-f16" ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

const adapter = await navigator.gpu.requestAdapter();
const hasShaderF16 = adapter.features.has("shader-f16");

const device = await adapter.requestDevice({
  requiredFeatures: hasShaderF16 ? ["shader-f16"] : [],
});

const header = hasShaderF16
  ? `enable f16;
     alias min16float = f16;`
  : `alias min16float = f32;`;

const code = `
  ${header}

  @compute @workgroup_size(1)
  fn main() {
    const c = vec3<min16float>(1.0, 2.0, 3.0);
  }
`;

ก้าวข้ามขีดจำกัด

จำนวนไบต์สูงสุดที่จำเป็นในการจัดเก็บตัวอย่าง (พิกเซลหรือพิกเซลย่อย) 1 รายการของข้อมูลเอาต์พุตของไปป์ไลน์การแสดงผลในการแนบสีทั้งหมดคือ 32 ไบต์โดยค่าเริ่มต้น ตอนนี้คุณขอได้สูงสุด 64 รายการโดยใช้ขีดจำกัด maxColorAttachmentBytesPerSample ดูตัวอย่างต่อไปนี้และออกคำสั่ง dawn:2036

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

if (adapter.limits.maxColorAttachmentBytesPerSample < 64) {
  // When the desired limit isn't supported, take action to either fall back to
  // a code path that does not require the higher limit or notify the user that
  // their device does not meet minimum requirements.
}

// Request highest limit of max color attachments bytes per sample.
const device = await adapter.requestDevice({
  requiredLimits: { maxColorAttachmentBytesPerSample: 64 },
});

เราได้เพิ่มขีดจำกัดของ maxInterStageShaderVariables และ maxInterStageShaderComponents ที่ใช้สำหรับการสื่อสารระหว่างสเตจในทุกแพลตฟอร์ม ดูรายละเอียดได้ที่ปัญหา dawn:1448

สำหรับแต่ละระยะของ Shader จำนวนสูงสุดของรายการเลย์เอาต์กลุ่มการเชื่อมโยงในเลย์เอาต์ของไปป์ไลน์ซึ่งเป็นบัฟเฟอร์พื้นที่เก็บข้อมูลคือ 8 โดยค่าเริ่มต้น ตอนนี้คุณขอได้สูงสุด 10 รายการโดยใช้ขีดจำกัดของ maxStorageBuffersPerShaderStage ดูปัญหา dawn:2159

เพิ่มขีดจำกัด maxBindGroupsPlusVertexBuffers ใหม่แล้ว ประกอบด้วยจำนวนสูงสุดของช่องกลุ่มการเชื่อมโยงและช่องบัฟเฟอร์จุดยอดที่ใช้พร้อมกัน โดยนับช่องว่างใดๆ ที่อยู่ต่ำกว่าดัชนีสูงสุด ค่าเริ่มต้นคือ 24 ดูปัญหา dawn:1849

การเปลี่ยนแปลงสถานะ Depth-Stencil

เพื่อปรับปรุงประสบการณ์ของนักพัฒนาซอฟต์แวร์ เราจึงไม่จำเป็นต้องใช้แอตทริบิวต์สถานะ Depth-Stencil depthWriteEnabled และ depthCompare เสมอไปอีกต่อไป โดยdepthWriteEnabled จะจำเป็นสำหรับรูปแบบที่มีความลึกเท่านั้น และdepthCompare จะไม่จำเป็นสำหรับรูปแบบที่มีความลึกหากไม่ได้ใช้เลย ดูปัญหา dawn:2132

การอัปเดตข้อมูลอะแดปเตอร์

ตอนนี้แอตทริบิวต์ข้อมูลอะแดปเตอร์ที่ไม่เป็นไปตามมาตรฐาน type และ backend พร้อมใช้งานแล้วเมื่อเรียกใช้ requestAdapterInfo() เมื่อผู้ใช้เปิดใช้Flag "ฟีเจอร์สำหรับนักพัฒนาซอฟต์แวร์ WebGPU" ที่ chrome://flags/#enable-webgpu-developer-features type อาจเป็น "GPU แยก" "GPU ในตัว" "CPU" หรือ "ไม่รู้จัก" backend เป็น "WebGPU", "D3D11", "D3D12", "metal", "vulkan", "openGL", "openGLES" หรือ "null" ดูปัญหา dawn:2112 และปัญหา dawn:2107

ภาพหน้าจอของ https://webgpureport.org ที่แสดงแบ็กเอนด์และประเภทในข้อมูลอะแดปเตอร์
ข้อมูลแบ็กเอนด์และประเภทของอแดปเตอร์ที่แสดงใน https://webgpureport.org

นำunmaskHintsพารามิเตอร์รายการที่ไม่บังคับใน requestAdapterInfo() ออกแล้ว ดูปัญหา dawn:1427

การหาปริมาณการค้นหาการประทับเวลา

การค้นหาการประทับเวลาช่วยให้แอปพลิเคชันวัดเวลาในการดำเนินการคำสั่ง GPU ได้อย่างแม่นยำในระดับนาโนวินาที อย่างไรก็ตาม ข้อกำหนด WebGPU ทำให้การค้นหาการประทับเวลาเป็นแบบไม่บังคับเนื่องจากข้อกังวลเกี่ยวกับการโจมตีแบบกำหนดเวลา ทีม Chrome เชื่อว่าการหาปริมาณการค้นหาการประทับเวลาเป็นทางออกที่ดีระหว่างความแม่นยำและความปลอดภัย โดยการลดความละเอียดลงเหลือ 100 ไมโครวินาที ดูissue dawn:1800

ใน Chrome ผู้ใช้สามารถปิดใช้การหาปริมาณการประทับเวลาได้โดยเปิดใช้Flag "ฟีเจอร์สำหรับนักพัฒนาซอฟต์แวร์ WebGPU" ที่ chrome://flags/#enable-webgpu-developer-features โปรดทราบว่าการเปิดใช้ฟีเจอร์ "timestamp-query" จะต้องใช้แฟล็กนี้ร่วมกับแฟล็กอื่นๆ การใช้งานยังอยู่ในช่วงทดลอง จึงต้องใช้แฟล็ก "การรองรับ WebGPU ที่ไม่ปลอดภัย" ที่ chrome://flags/#enable-unsafe-webgpu

ใน Dawn เราได้เพิ่มการสลับอุปกรณ์ใหม่ที่ชื่อ "timestamp_quantization" และเปิดใช้โดยค่าเริ่มต้น ข้อมูลโค้ดต่อไปนี้แสดงวิธีอนุญาตฟีเจอร์ "การค้นหาตามการประทับเวลา" เวอร์ชันทดลองโดยไม่มีการหาปริมาณการประทับเวลาเมื่อขออุปกรณ์

wgpu::DawnTogglesDescriptor deviceTogglesDesc = {};

const char* allowUnsafeApisToggle = "allow_unsafe_apis";
deviceTogglesDesc.enabledToggles = &allowUnsafeApisToggle;
deviceTogglesDesc.enabledToggleCount = 1;

const char* timestampQuantizationToggle = "timestamp_quantization";
deviceTogglesDesc.disabledToggles = &timestampQuantizationToggle;
deviceTogglesDesc.disabledToggleCount = 1;

wgpu::DeviceDescriptor desc = {.nextInChain = &deviceTogglesDesc};

// Request a device with no timestamp quantization.
myAdapter.RequestDevice(&desc, myCallback, myUserData);

ฟีเจอร์การทำความสะอาดช่วงฤดูใบไม้ผลิ

เราได้เปลี่ยนชื่อฟีเจอร์ทดลอง "timestamp-query-inside-passes" เป็น "chromium-experimental-timestamp-query-inside-passes" เพื่อให้ผู้พัฒนาทราบอย่างชัดเจนว่าฟีเจอร์นี้เป็นฟีเจอร์ทดลองและปัจจุบันใช้ได้เฉพาะในเบราว์เซอร์ที่ใช้ Chromium เท่านั้น ดูปัญหา dawn:1193

ระบบได้นำฟีเจอร์ "pipeline-statistics-query" ที่เป็นเวอร์ชันทดลองออกแล้วเนื่องจากไม่ได้พัฒนาต่อ โดยฟีเจอร์นี้มีการใช้งานเพียงบางส่วนเท่านั้น ดูissue chromium:1177506

ซึ่งเป็นเพียงไฮไลต์สำคัญบางส่วนเท่านั้น ดูรายการคอมมิตทั้งหมด

มีอะไรใหม่ใน WebGPU

รายการทุกอย่างที่ครอบคลุมในซีรีส์มีอะไรใหม่ใน WebGPU

Chrome 140

Chrome 139

Chrome 138

Chrome 137

Chrome 136

Chrome 135

Chrome 134

Chrome 133

Chrome 132

Chrome 131

Chrome 130

Chrome 129

Chrome 128

Chrome 127

Chrome 126

Chrome 125

Chrome 124

Chrome 123

Chrome 122

Chrome 121

Chrome 120

Chrome 119

Chrome 118

Chrome 117

Chrome 116

Chrome 115

Chrome 114

Chrome 113