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

François Beaufort
François Beaufort

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

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

ในการเปรียบเทียบ ในอุปกรณ์ 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 ประเภทนี้ใช้ได้ในโมดูลเชดเดอร์ WGSL เฉพาะในกรณีที่คุณเปิดใช้f16ส่วนขยาย WGSL ด้วย enable f16; มิฉะนั้น createShaderModule() จะสร้างข้อผิดพลาดในการตรวจสอบ ดูตัวอย่างขั้นต่ำต่อไปนี้และ issue 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 โปรดดูตัวอย่างต่อไปนี้และ issue 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 ที่ใช้ในการสื่อสารระหว่างระยะต่างๆ ได้เพิ่มขึ้นในทุกแพลตฟอร์ม ดูรายละเอียดได้ที่ issue dawn:1448

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

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

การเปลี่ยนแปลงสถานะเชิงลึก

เราได้ปรับปรุงประสบการณ์การใช้งานสำหรับนักพัฒนาแอปโดยไม่จำเป็นต้องใช้แอตทริบิวต์สถานะเชิงลึก 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" โปรดดู issue dawn:2112 และ issue dawn:2107

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

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

การแปลงค่าการค้นหาการประทับเวลา

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

ใน Chrome ผู้ใช้สามารถปิดใช้การปัดเศษการประทับเวลาได้โดยเปิดใช้Flag "ฟีเจอร์สำหรับนักพัฒนาซอฟต์แวร์ WebGPU" ที่ chrome://flags/#enable-webgpu-developer-features โปรดทราบว่าการแจ้งนี้เพียงอย่างเดียวจะไม่เปิดใช้ฟีเจอร์ "timestamp-query" การใช้งานยังอยู่ในขั้นทดลอง จึงต้องใช้ Flag "การรองรับ 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" เวอร์ชันทดลองซึ่งติดตั้งใช้งานเพียงบางส่วนออกแล้ว เนื่องจากไม่มีการพัฒนาฟีเจอร์นี้อีกต่อไป ดูปัญหา chromium:1177506

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

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

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

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