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

لا تتوافق بعض وحدات معالجة الرسومات مع قيم الفاصلة العائمة ذات 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". يمكنك الاطّلاع على issue dawn:2112 وissue 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.

تمت إزالة ميزة "pipeline-statistics-query" التجريبية التي تم تنفيذها جزئيًا فقط، لأنّه لم يعُد يتم تطويرها. راجِع المشكلة 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