מה חדש ב-WebGPU (Chrome {8/}120)

François Beaufort
François Beaufort

תמיכה בערכי נקודה צפה (floating-point) של 16 ביט ב-WGSL

ב-WGSL, הסוג f16 הוא קבוצת ערכי נקודה צפה (floating-point) של 16 ביט של הפורמט הבינארי IEEE-754 (דיוק חצי). המשמעות היא שהוא משתמש ב-16 ביטים כדי לייצג מספר נקודה צפה (floating-point), בניגוד ל-32 ביטים של נקודה צפה רגילה ברמת דיוק יחידה (f32). הגודל הקטן הזה יכול להוביל לשיפורים משמעותיים בביצועים, במיוחד בעיבוד כמויות גדולות של נתונים.

לשם השוואה, במכשיר Apple M1 Pro, ההטמעה של f16 בדגמי Llama2 7B שנעשה בהם שימוש בהדגמת הצ'אט של WebLLM מהירה יותר באופן משמעותי מההטמעה של f32. יש גם שיפור של 28% במהירות המילוי מראש ושיפור של 41% במהירות הפענוח, כפי שמוצג בצילומי המסך הבאים.

צילום מסך של הדגמות צ'אט של WebLLM בדגמים f32 ו-f16 Llama2 7B.
הדגמות של צ'אט WebLLM עם f32 (משמאל) ו-f16 (ימין) דגמי Llama2 7B.

לא כל יחידות ה-GPU תומכות בערכי נקודה צפה (floating-point) של 16 ביט. כשהתכונה "shader-f16" תהיה זמינה ב-GPUAdapter, עכשיו אפשר לבקש GPUDevice עם התכונה הזו וליצור מודול של תוכנת הצללה (shader) של WGSL שמשתמש בשיטה 'נקודה צפה בחצי דיוק' f16. ניתן להשתמש בסוג הזה במודול של ההצללה (shader) של WGSL רק אם מפעילים את תוסף f16 WGSL עם 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);
  }
`;

בוחנים את הגבולות

כברירת מחדל, מספר הבייטים המקסימלי שדרוש כדי להחזיק דגימה אחת (פיקסל או תת-פיקסל) של נתוני פלט של צינור עיבוד הנתונים לעיבוד בכל קובצי הצבעים, הוא 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 שמשמשות לתקשורת בין שלבים הוגדלו בכל הפלטפורמות. לפרטים, אפשר לעיין בבעיה בזריחה:1448.

בכל שלב של תוכנת הצללה (shader), המספר המקסימלי של רשומות פריסה של קבוצה של קישור בפריסת צינור עיבוד נתונים, שהן מאגרי אחסון זמניים, הוא 8 כברירת מחדל. עכשיו אפשר לבקש עד 10 בקשות באמצעות המגבלה של maxStorageBuffersPerShaderStage. להצגת השחר:2159.

נוספה מגבלה חדשה של maxBindGroupsPlusVertexBuffers. המדד הזה כולל את המספר המקסימלי של משבצות לקבוצת קישורים ויחידות של מאגר קודקוד שנעשה בהן שימוש בו-זמנית, ונספרת כל המשבצות הריקות שמתחת לאינדקס הגבוה ביותר. ערך ברירת המחדל שלו הוא 24. להצגת הבעיה: שחר: 1849.

שינויים במצב העומק של שבלונה

כדי לשפר את חוויית הפיתוח, לא תמיד צריך לציין את מאפייני מצב העומק depthWriteEnabled ו-depthCompare: depthWriteEnabled נדרש רק לפורמטים עם עומק, ו-depthCompare לא נדרש לפורמטים עם עומק אם לא נעשה בהם שימוש כלל. להצגת הבעיה: שחר:2132.

עדכוני מידע על המתאם

מאפיינים לא סטנדרטיים של מתאמים מסוג type ו-backend זמינים עכשיו בתגובה לקריאה ל-requestAdapterInfo() לאחר שהמשתמש הפעיל את הדגל של 'תכונות למפתחים של WebGPU' ב-chrome://flags/#enable-webgpu-developer-features. השדה type יכול להיות GPU שונה, מעבד גרפי משולב, מעבד (CPU) או לא ידוע. הערך backend הוא "WebGPU" , "D3D11" , "D3D12" , "metaal" , "vulkan" , "openGL" , "openGLES" או "null". מעיינים בבעיה בזריקת dawn:2112 ובבעיה בזריחה: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.

בזריחה נוספה מתג חדש של המכשיר שנקרא '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. להצגת הבעיה: שחר:1193.

התכונה הניסיונית "צינור נתונים סטטיסטיים-שאילתה", שהוטמעה באופן חלקי בלבד, הוסרה מכיוון שהיא לא נמצאת עוד בפיתוח. מידע נוסף על בעיה כרום:1177506.

המאמר הזה מתייחס רק לחלק מההדגשים העיקריים. כדאי לעיין ברשימת ההתחייבויות המקיפה.

מה חדש ב-WebGPU

רשימה של כל מה שמכוסה בסדרה מה חדש ב-WebGPU.

Chrome 125

Chrome 124

Chrome 123

גרסה 122 של Chrome

גרסה 121 של Chrome

Chrome 120

גרסה 119 של Chrome

גרסה 118 של Chrome

גרסה 117 של Chrome

גרסה 116 של Chrome

Chrome 115

Chrome 114

גרסה 113 של Chrome