מה חדש ב-WebGPU (Chrome123)

François Beaufort
François Beaufort

תמיכה בפונקציות מובנות של DP4a ב-WGSL

DP4a (מוצר נקודה של 4 אלמנטים וצבירה) מתייחס לקבוצת הוראות GPU שנמצאות בשימוש נפוץ בהסקת מסקנות למידה עמוקה לצורך קוונטיזציה. הוא משתמש ביעילות במוצרים מסוג נקודות של 8 ביט כדי להאיץ את החישוב של מודלים כמותיים כאלה. הוא יכול לחסוך (עד 75%) מרוחב הפס בזיכרון וברשת ולשפר את הביצועים של כל מודל למידת המכונה בהסקת מסקנות בהשוואה לגרסת f32 שלהם. לכן, השימוש בו נרחב מאוד במסגרות AI פופולריות רבות.

כשתוסף השפה של WGSL "packed_4x8_integer_dot_product" מופיע ב-navigator.gpu.wgslLanguageFeatures, אפשר עכשיו להשתמש בסקלרים שלמים של 32 ביט שאורזים וקטורים שלמים ב-4 רכיבים של מספרים שלמים של 8 ביט כקלט להוראות למוצר נקודה בקוד ההצללה של WGSL באמצעות הפונקציות המובנות dot4U8Packed ו-dot4I8Packed. אפשר גם להשתמש בהוראות אריזה ופריקה של וקטורים דחוסים של 4 רכיבים של מספרים שלמים של 8 ביט באמצעות פונקציות מובנות של WGSL, pack4xI8, pack4xU8, pack4xI8Clamp, pack4xU8Clamp, unpack4xI8 ו-unpack4xU8.

מומלץ להשתמש ב-דורש-הוראת כדי לאותת שיכול להיות שאי-ניידות באמצעות requires packed_4x8_integer_dot_product; בחלק העליון של קוד תוכנת ההצללה (shader) של WGSL. אפשר לעיין בדוגמה הבאה ואת גוון הבעיה:1497.

if (!navigator.gpu.wgslLanguageFeatures.has("packed_4x8_integer_dot_product")) {
  throw new Error(`DP4a built-in functions are not available`);
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const shaderModule = device.createShaderModule({ code: `
  requires packed_4x8_integer_dot_product;

  fn main() {
    const result: u32 = dot4U8Packed(0x01020304u, 0x02040405u); // 42
  }`,
});

תודה מיוחדת לצוות ה-Web Graphics של Intel בשנגחאי, שהביא את המפרט והיישום הזה עד הסוף!

פרמטרים לא מוגבלים של מצביע ב-WGSL

תוסף השפה של WGSL "unrestricted_pointer_parameters" משחרר את ההגבלות שחלות על המצביעים שניתן להעביר לפונקציות WGSL:

  • מצביעי פרמטרים של storage, uniform ו-workgroup כתובות לפונקציות שהוצהרו על ידי המשתמש.

  • העברת מצביעות לרכיבי מבנה ורכיבי מערך לפונקציות שהוצהרו על ידי המשתמש.

כדאי לעיין במאמר Pointers כפרמטרים של פונקציה | סיור ב-WGSL כדי לקבל מידע נוסף.

אפשר לזהות את התכונה הזו באמצעות navigator.gpu.wgslLanguageFeatures. מומלץ תמיד להשתמש ב-דורש-הוראת כדי לאותת על פוטנציאל לאי-ניידות באמצעות requires unrestricted_pointer_parameters; בחלק העליון של קוד תוכנת ההצללה (shader) של WGSL. מומלץ לעיין בדוגמה הבאה, בשינויים במפרט WGSL ובגוון הבעיה:2053.

if (!navigator.gpu.wgslLanguageFeatures.has("unrestricted_pointer_parameters")) {
  throw new Error(`Unrestricted pointer parameters are not available`);
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const shaderModule = device.createShaderModule({ code: `
  requires unrestricted_pointer_parameters;

  @group(0) @binding(0) var<storage, read_write> S : i32;

  fn func(pointer : ptr<storage, i32, read_write>) {
    *pointer = 42;
  }

  @compute @workgroup_size(1)
  fn main() {
    func(&S);
  }`
});

תחביר תחביר (sugar) לביטול התייחסויות של מרוכבים ב-WGSL

כשתוסף השפה של WGSL "pointer_composite_access" מופיע ב-navigator.gpu.wgslLanguageFeatures, קוד ההצללה של WGSL תומך עכשיו בגישה לרכיבים של סוגי נתונים מורכבים באמצעות אותו תחביר נקודה (.) בין אם אתם עובדים ישירות עם הנתונים או עם מצביע אליהם. ככה זה עובד:

  • אם foo הוא מצביע: foo.bar הוא דרך נוחה יותר לכתוב (*foo).bar. בדרך כלל יש צורך בכוכבית (*) כדי להפוך את הסמן ל'הפניה' שאפשר להחריג, אבל עכשיו גם המצביעים וגם ההפניות דומים יותר וכמעט ניתנים להחלפה.

  • אם foo הוא לא מצביע: האופרטור נקודה (.) פועל בדיוק כמו שהתרגלת אליו לגישה ישירה לחברים.

באופן דומה, אם pa הוא מצביע שמאחסן את כתובת ההתחלה של מערך, השימוש ב-pa[i] נותן לך גישה ישירה למיקום הזיכרון שבו מאוחסן הרכיב 'i של המערך הזה.

מומלץ להשתמש ב-דורש-הוראת כדי לאותת שיכול להיות שאי-ניידות באמצעות requires pointer_composite_access; בחלק העליון של קוד תוכנת ההצללה (shader) של WGSL. אפשר לעיין בדוגמה הבאה ואת גוון הבעיה:2113.

if (!navigator.gpu.wgslLanguageFeatures.has("pointer_composite_access")) {
  throw new Error(`Pointer composite access is not available`);
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const shaderModule = device.createShaderModule({ code: `
  requires pointer_composite_access;

  fn main() {
    var a = vec3f();
    let p : ptr<function, vec3f> = &a;
    let r1 = (*p).x; // always valid.
    let r2 = p.x; // requires pointer composite access.
  }`
});

מצב קריאה בלבד נפרד להבטי שבלונה ובעומק

בעבר, קבצים מצורפים עם תוכן עובי לקריאה בלבד באישורי רינדור חייבו את שני ההיבטים (עומק וסטנסיל) לקריאה בלבד. ההגבלה הזו הוסרה. עכשיו אפשר להשתמש בהיבט העומק במצב של קריאה בלבד, למשל עבור מעקב אחרי צלליות, בזמן שמאגר הנתונים הזמני של שבלונה נכתב כדי לזהות פיקסלים לעיבוד נוסף. ראו גיליון dawn:2146.

עדכונים לגבי זריחה

הקריאה החוזרת של השגיאה שלא תועדה אצל wgpuDeviceSetUncapturedErrorCallback() תופעל עכשיו מיד כשהשגיאה מתרחשת. זה מה שמפתחים מצפים לקבל ורוצים לצורכי ניפוי באגים באופן עקבי. ראו שינוי dawn:173620.

השיטה wgpuSurfaceGetPreferredFormat() מ-webgpu.h API הוטמעה. ראו גיליון dawn:1362.

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

מה חדש ב-WebGPU

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

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