الميزات الجديدة في WebGPU (الإصدار 120 من Chrome)

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 التوضيحية للمحادثات باستخدام نماذج f32 وf16 Llama2 7B
عروض توضيحية للدردشة في WebLLM باستخدام نماذج Llama2 7B من f32 (على اليمين) وf16 (على اليسار)

لا تتوافق بعض وحدات معالجة الرسومات مع قيم الفاصلة العائمة ذات 16 بت. عندما تتوفّر ميزة "shader-f16" في GPUAdapter، يمكنك الآن طلب GPUDevice باستخدام هذه الميزة وإنشاء وحدة تظليل WGSL تستفيد من نوع النقطة العائمة بنصف الدقة f16. لا يمكن استخدام هذا النوع في وحدة تظليل 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 في رمز وحدة تظليل 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);
  }
`;

تجاوز الحدود

الحد الأقصى لعدد البايتات اللازمة لتخزين عيّنة واحدة (بكسل أو بكسل فرعي) من بيانات ناتج مسار العرض، في جميع مرفقات الألوان، هو 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.

بالنسبة إلى كل مرحلة من مراحل التظليل، يبلغ الحدّ الأقصى لعدد إدخالات تنسيق مجموعة الربط في جميع تنسيقات خطوط الأنابيب التي تمثّل مخازن مؤقتة للتخزين 8 بشكلٍ تلقائي. يمكنك الآن طلب ما يصل إلى 10 أجهزة باستخدام الحدّ الأقصى maxStorageBuffersPerShaderStage. اطّلِع على المشكلة dawn:2159.

تمّت إضافة حدّ أقصى جديد maxBindGroupsPlusVertexBuffers. يتكوّن من الحدّ الأقصى لعدد خانات مجموعة الربط ومخزن مؤقت للرؤوس المستخدَمة في الوقت نفسه، مع احتساب أي خانات فارغة أسفل الفهرس الأعلى. القيمة التلقائية هي 24. اطّلِع على المشكلة dawn:1849.

التغييرات على حالة استنسال العمق

لتحسين تجربة المطوّرين، لم يعُد من الضروري دائمًا استخدام سمات حالة العمق والقطع depthWriteEnabled وdepthCompare: لا يكون depthWriteEnabled مطلوبًا إلا للتنسيقات التي تتضمّن عمقًا، ولا يكون depthCompare مطلوبًا للتنسيقات التي تتضمّن عمقًا إذا لم يتم استخدامها على الإطلاق. راجِع المشكلة dawn:2132.

تعديلات على معلومات المحوّل

تتوفّر الآن سمات معلومات محوّل type وbackend غير العادية عند طلب requestAdapterInfo() عندما يفعّل المستخدم العلامة "ميزات مطوّري WebGPU" في chrome://flags/#enable-webgpu-developer-features. يمكن أن تكون قيمة type "وحدة معالجة رسومات منفصلة" أو "وحدة معالجة رسومات مدمجة" أو "وحدة معالجة مركزية" أو "غير معروف". تكون قيمة backend إما "WebGPU" أو "D3D11" أو "D3D12" أو "metal" أو "vulkan" أو "openGL" أو "openGLES" أو "null". يمكنك الاطّلاع على المشكلة dawn:2112 والمشكلة dawn:2107.

لقطة شاشة من https://webgpureport.org تعرض الواجهة الخلفية والنوع في معلومات المحوّل
معلومات المحوّل الخلفي ونوعه المعروض على https://webgpureport.org.

تمت إزالة مَعلمة القائمة unmaskHints الاختيارية في requestAdapterInfo(). راجِع المشكلة dawn:1427.

تحديد كمية طلبات البحث المستندة إلى الطابع الزمني

تسمح طلبات الطابع الزمني للتطبيقات بقياس وقت تنفيذ أوامر وحدة معالجة الرسومات بدقة تصل إلى نانوثانية. ومع ذلك، تجعل مواصفات WebGPU طلبات البحث عن الطوابع الزمنية اختيارية بسبب المخاوف بشأن هجمات التوقيت. يرى فريق Chrome أنّ تحديد عدد خانات الأرقام العشرية في طلبات البحث عن الطوابع الزمنية يقدّم حلاً وسطًا جيدًا بين الدقة والأمان، وذلك من خلال تقليل الدقة إلى 100 ميكروثانية. اطّلِع على المشكلة dawn:1800.

في Chrome، يمكن للمستخدمين إيقاف تحديد الكمية الزمنية للطوابع الزمنية من خلال تفعيل الميزة التجريبية "ميزات مطوّري WebGPU" على chrome://flags/#enable-webgpu-developer-features. يُرجى العِلم أنّ هذا الخيار وحده لا يفعّل ميزة "timestamp-query". لا يزال تنفيذها تجريبيًا، وبالتالي يتطلّب تفعيل العلامة "Unsafe WebGPU Support" في 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.

تمت إزالة ميزة "طلب إحصاءات خط الأنابيب" التجريبية التي تم تنفيذها جزئيًا فقط، لأنّه لم يعُد يتم تطويرها. راجِع المشكلة chromium:1177506.

هذا يشمل بعض النقاط الرئيسية فقط. اطّلِع على قائمة عمليات الدمج الشاملة.

الميزات الجديدة في WebGPU

قائمة بكل ما تم تناوله في سلسلة الميزات الجديدة في WebGPU

Chrome 143

Chrome 142

Chrome 141

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