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

François Beaufort
François Beaufort

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

ב-WGSL, הסוג f16 הוא קבוצת הערכים של נקודה צפה באורך 16 ביט בפורמט binary16 (חצי דיוק) של IEEE-754. המשמעות היא שהיא משתמשת ב-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 עם התכונה הזו וליצור מודול של שַדְר (shader) ב-WGSL שמנצל את סוג הנקודה הצפה ברמת דיוק חצי f16. אפשר להשתמש בסוג הזה במודול ה-WGSL shader רק אם מפעילים את התוסף WGSL של f16 באמצעות 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. issue dawn:1849

שינויים במצב של סטנציאל עומק

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

עדכונים של פרטי המתאם

מאפייני המידע הלא סטנדרטיים של המתאם type ו-backend זמינים עכשיו בקריאה ל-requestAdapterInfo() כשהמשתמש הפעיל את הדגל 'WebGPU Developer Features' ב-chrome://flags/#enable-webgpu-developer-features. הערך של type יכול להיות 'GPU נפרד', 'GPU משולב', 'מעבד' או 'לא ידוע'. הערך של backend הוא WebGPU,‏ D3D11,‏ D3D12,‏ metal,‏ vulkan,‏ openGL,‏ openGLES או null. אפשר לעיין בבעיה dawn:2112 ובבעיה dawn:2107.

צילום מסך של https://webgpureport.org עם מידע על הקצה העורפי ועל סוג המתאם.
הקצה העורפי והסוג של פרטי המתאם מוצגים בכתובת https://webgpureport.org.

הפרמטר האופציונלי הרשימה unmaskHints ב-requestAdapterInfo() הוסר. ראו גיליון dawn:1427.

כימות של שאילתות עם חותמות זמן

שאילתות של חותמות זמן מאפשרות לאפליקציות למדוד את זמן הביצוע של פקודות GPU ברמת דיוק של ננו-שנייה. עם זאת, לפי מפרט WebGPU, שאילתות של חותמות זמן הן אופציונליות בגלל חששות לגבי התקפת תזמון. צוות Chrome סבור שאפשר להגיע לפשרה טובה בין דיוק לאבטחה על ידי הפחתת הרזולוציה של שאילתות של חותמות זמן ל-100 מיקרו-שניות. issue dawn:1800

ב-Chrome, המשתמשים יכולים להשבית את התקציבים של חותמות הזמן על ידי הפעלת הדגל 'WebGPU Developer Features' בקטע 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. ראו גיליון dawn:1193.

התכונה הניסיונית 'pipeline-statistics-query', שהוטמעה רק חלקית, הוסרה כי היא לא מתפתחת יותר. בעיה chromium:1177506

הסקירה הזו כוללת רק חלק מהנקודות העיקריות. רשימת ההצהרות המלאה

מה חדש ב-WebGPU

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

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