ویژگی‌های جدید WebGPU (‏Chrome 120)

François Beaufort
François Beaufort

پشتیبانی از مقادیر ممیز شناور ۱۶ بیتی در WGSL

در WGSL، نوع f16 مجموعه مقادیر ممیز شناور ۱۶ بیتی با قالب IEEE-754 binary16 (دقت نصف) است. این یعنی از ۱۶ بیت برای نمایش عدد ممیز شناور استفاده می‌کند، درحالی‌که برای عدد ممیز شناور تک‌دقت معمولی از ۳۲ بیت استفاده می‌شود (f32). این اندازه کوچک‌تر می‌تواند منجر به بهبود قابل‌توجه عملکرد شود، به‌ویژه هنگام پردازش مقادیر زیادی داده.

برای مقایسه، در دستگاه Apple M1 Pro، پیاده‌سازی f16 مدل‌های Llama2 7B که در نمونه نمایشی گپ WebLLM استفاده می‌شود به‌طور قابل‌توجهی سریع‌تر از پیاده‌سازی f32 است، به‌طوری‌که سرعت پیش‌تکمیل ۲۸٪ و سرعت رمزگشایی ۴۱٪ بهبود یافته است، همان‌طور که در نماگرفت‌های زیر نشان داده شده است.

نماگرفت از نمایش‌های گپ WebLLM با مدل‌های f32 و f16 Llama2 7B.
نسخه‌های نمایشی گپ WebLLM با مدل‌های f32 (راست) و f16 (چپ) Llama2 7B.

همه واحدهای GPU از مقادیر ممیز شناور ۱۶ بیتی پشتیبانی نمی‌کنند. وقتی ویژگی "shader-f16" در GPUAdapter دردسترس باشد، اکنون می‌توانید GPUDevice را با این ویژگی درخواست کنید و واحد سایه‌زن 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...

بااستفاده از alias بسته به پشتیبانی ویژگی "shader-f16"، می‌توان از هر دو نوع f16 و f32 در کد واحد سایه‌زن WGSL پشتیبانی کرد، همان‌طور که در تکه‌کد زیر نشان داده شده است.

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);
  }
`;

محدودیت‌ها را کنار بزنید

حداکثر تعداد بایت‌های لازم برای نگهداری یک نمونه (پیکسل یا زیرپیکسل) از داده‌های برونداد خط لوله پردازش، در سراسر پیوست‌های رنگ، به‌طور پیش‌فرض ۳۲ بایت است. اکنون بااستفاده از حد 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 را ببینید.

برای هر مرحله سایه‌زن، حداکثر تعداد ورودی‌های طرح‌بندی گروه پیوند در سراسر طرح‌بندی خط لوله که بافرهای ذخیره‌سازی هستند به‌طور پیش‌فرض ۸ است. اکنون بااستفاده از حد maxStorageBuffersPerShaderStage می‌توانید حداکثر ۱۰ درخواست کنید. issue dawn:2159 را ببینید.

محدودیت جدید maxBindGroupsPlusVertexBuffers اضافه شده است. این مقدار شامل حداکثر تعداد جایگاه‌های گروه پیوند و بافر رأس است که به‌طور هم‌زمان استفاده می‌شوند و جایگاه‌های خالی زیر بالاترین شاخص را نیز دربرمی‌گیرد. مقدار پیش‌فرض آن ۲۴ است. طلوع مشکل:۱۸۴۹ را ببینید.

تغییرات در وضعیت عمق-استنسیل

برای بهبود تجربه توسعه‌دهنده، وضعیت عمق-استنسیل depthWriteEnabled و depthCompare دیگر همیشه الزامی نیستند: depthWriteEnabled فقط برای قالب‌های دارای عمق الزامی است، و depthCompare برای قالب‌های دارای عمق درصورتی‌که اصلاً استفاده نشود الزامی نیست. issue 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() برداشته شده است. issue dawn:1427 را ببینید.

کوانتیزاسیون پُرسمان‌های مُهر زمان

پُرسمان‌های مُهر زمان به برنامه‌ها امکان می‌دهد زمان اجرای دستورات GPU را با دقت نانوثانیه اندازه‌گیری کنند. بااین‌حال، مشخصات WebGPU به‌دلیل نگرانی‌های مربوط به حمله زمان‌بندی، پرسش‌های مُهر زمان را اختیاری می‌کند. تیم Chrome معتقد است که با کاهش دقت به ۱۰۰ میکروثانیه، کوانتیزه کردن پُرسمان‌های مُهر زمان توازنی خوب بین دقت و امنیت ایجاد می‌کند. issue dawn:1800 را ببینید.

در Chrome، کاربران می‌توانند با فعال کردن پرچم «ویژگی‌های توسعه‌دهنده 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 دردسترس است. issue dawn:1193 را ببینید.

ویژگی آزمایشی «pipeline-statistics-query» که فقط به‌صورت جزئی پیاده‌سازی شده بود برداشته شده است زیرا دیگر توسعه داده نمی‌شود. issue chromium:1177506 را ببینید.

این فقط برخی‌از نکات برجسته کلیدی را پوشش می‌دهد. فهرست کامل تعهدات را بررسی کنید.

ویژگی‌های جدید WebGPU

فهرستی از همه مواردی که در مجموعه ویژگی‌های جدید WebGPU پوشش داده شده است.

‫۱۵۵-۱۵۶ Chrome

‫۱۵۳-۱۵۴ Chrome

Chrome 151-152

‫۱۴۹-۱۵۰ Chrome

‫۱۴۷-۱۴۸ Chrome

‫۱۴۶ Chrome

‫Chrome 145

‫۱۴۴ Chrome

‫۱۴۳ Chrome

‫۱۴۲ Chrome

Chrome 141

‫۱۴۰ Chrome

Chrome 139

‫Chrome 138

Chrome 137

‫Chrome 136

‫۱۳۵ Chrome

‫۱۳۴ Chrome

‫Chrome 133

‫۱۳۲ Chrome

‫۱۳۱ Chrome

‫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