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

François Beaufort
François Beaufort

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

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

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

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

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

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

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

การเปลี่ยนแปลงสถานะของฉลุลายความลึก

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

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

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

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

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

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

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

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

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

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 เท่านั้นในขณะนี้ ดูรุ่งอรุณของปัญหา:1193

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

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

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

รายการของทุกอย่างที่มีการพูดถึงในซีรีส์มีอะไรใหม่ใน WebGPU

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