موارد جدید در WebGPU (Chrome 120)

فرانسوا بوفور
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.

همه پردازنده‌های گرافیکی از مقادیر ممیز شناور ۱۶ بیتی پشتیبانی نمی‌کنند. وقتی ویژگی "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);
  }
`;

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

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

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

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

تغییرات در حالت عمق شابلون

برای بهبود تجربه توسعه‌دهنده، حالت الگوی عمق depthWriteEnabled و ویژگی‌های depthCompare دیگر همیشه مورد نیاز نیستند: depthWriteEnabled فقط برای فرمت‌های دارای depth مورد نیاز است و depthCompare برای فرمت‌های دارای depth در صورتی که اصلاً استفاده نشوند، مورد نیاز نیست. به شماره dawn:2132 مراجعه کنید.

به‌روزرسانی‌های اطلاعات آداپتور

ویژگی‌های اطلاعات آداپتور type و backend غیر استاندارد، اکنون با فراخوانی requestAdapterInfo() در دسترس هستند، زمانی که کاربر پرچم "WebGPU Developer Features" را در chrome://flags/#enable-webgpu-developer-features فعال کرده باشد. type می‌تواند "discrete GPU"، "integrated GPU"، "CPU" یا "unknown" باشد. backend می‌تواند "WebGPU"، "D3D11"، "D3D12"، "metal"، "vulkan"، "openGL"، "openGLES" یا "null" باشد. به issue dawn:2112 و issue dawn:2107 مراجعه کنید.

تصویری از https://webgpureport.org که شامل backend است و اطلاعات آداپتور را تایپ کنید.
اطلاعات و نوع آداپتور در بک‌اند و در https://webgpureport.org نشان داده شده است.

پارامتر اختیاری unmaskHints list در requestAdapterInfo() حذف شده است. به شماره dawn:1427 مراجعه کنید.

کوئستیزاسیون کوئست‌سنجی کوئست‌سنجی کوئست‌سنجی با مهر زمانی

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

در کروم، کاربران می‌توانند با فعال کردن پرچم "WebGPU Developer Features" در chrome://flags/#enable-webgpu-developer-features کوانتیزاسیون مهر زمانی را غیرفعال کنند. توجه داشته باشید که این پرچم به تنهایی ویژگی "timestamp-query" را فعال نمی‌کند. پیاده‌سازی آن هنوز آزمایشی است و بنابراین نیاز به پرچم "Unsafe WebGPU Support" در chrome://flags/#enable-unsafe-webgpu دارد.

در داون، یک گزینه‌ی جدید برای دستگاه به نام "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» تغییر نام داده است تا برای توسعه‌دهندگان روشن شود که این ویژگی آزمایشی است و فعلاً فقط در مرورگرهای مبتنی بر کرومیوم در دسترس است. به شماره dawn:1193 مراجعه کنید.

ویژگی آزمایشی "pipeline-statistics-query" که فقط تا حدی پیاده‌سازی شده بود، حذف شده است زیرا دیگر در حال توسعه نیست. به شماره chrome:1177506 مراجعه کنید.

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

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

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

کروم ۱۴۲

کروم ۱۴۱

کروم ۱۴۰

کروم ۱۳۹

کروم ۱۳۸

کروم ۱۳۷

کروم ۱۳۶

کروم ۱۳۵

کروم ۱۳۴

کروم ۱۳۳

کروم ۱۳۲

کروم ۱۳۱

کروم ۱۳۰

کروم ۱۲۹

کروم ۱۲۸

کروم ۱۲۷

کروم ۱۲۶

کروم ۱۲۵

کروم ۱۲۴

کروم ۱۲۳

کروم ۱۲۲

کروم ۱۲۱

کروم ۱۲۰

کروم ۱۱۹

کروم ۱۱۸

کروم ۱۱۷

کروم ۱۱۶

کروم ۱۱۵

کروم ۱۱۴

کروم ۱۱۳