WebGPU: ביטול הנעילה של גישת GPU מודרנית בדפדפן

למד כיצד WebGPU פותחת את העוצמה של ה-GPU להשגת ביצועים מהירים יותר של למידת מכונה ועיבוד גרפיקה טוב יותר.

WebGPU API החדש מעניק שיפורי ביצועים עצומים בעומסי עבודה של גרפיקה ושל למידת מכונה. המאמר הזה בוחן את האופן שבו WebGPU מהווה שיפור לעומת הפתרון הנוכחי של WebGL, ונקבל הצצה על ההתפתחויות העתידיות. אך תחילה, נספק הקשר למה פותח ה-WebGPU.

הקשר ב-WebGPU

WebGL הגיע ל-Chrome בשנת 2011. WebGL מאפשר לאפליקציות אינטרנט לנצל מעבדי GPU וליהנות מחוויות מדהימות באינטרנט - מ-Google Earth, לסרטוני מוזיקה אינטראקטיביים, להדרכות מפורטות בנושא עולם הנדל"ן בתלת-ממד ועוד. טכנולוגיית WebGL התבססה על משפחת ממשקי ה-API של OpenGL שפותחה לראשונה ב-1992. זה מזמן! ואפשר לדמיין שחומרת GPU התפתחה באופן משמעותי מאז.

כדי להתקדם בהתפתחות הזו, פותח סוג חדש של ממשקי API שמאפשרים אינטראקציה יעילה יותר עם חומרת GPU מודרנית. ממשקי API כמו Direct3D 12 , Metal ו-Vulkan. ממשקי ה-API החדשים האלה תמכו בתרחישים לדוגמה חדשים ותובעניים לתכנות GPU, כמו תוספת הכוח בלמידת מכונה ופיתוחים באלגוריתמים של רינדור. WebGPU היא היורשת של WebGL, שמביאה את הפיתוחים של סוג חדש זה של ממשקי API מודרניים לאינטרנט.

WebGPU פותחת בפניכם אפשרויות רבות של תכנות GPU בדפדפן. הוא משקף בצורה טובה יותר את אופן הפעולה של חומרת GPU מודרנית, תוך מתן בסיס ליכולות מתקדמות יותר של GPU בעתיד. ה-API פועל בקבוצת ה-GPU for the Web של W3C מאז 2017, והוא שיתוף פעולה בין חברות רבות כמו Apple, Google, Mozilla, Microsoft ו-Intel. ועכשיו, אחרי 6 שנים של עבודה, אנחנו שמחים להודיע שאחת מהתוספות הכי גדולות לפלטפורמת האינטרנט זמינה סוף סוף!

WebGPU זמין היום ב-Chrome 113 ב-ChromeOS, ב-macOS וב-Windows, ובקרוב נוסיף עוד פלטפורמות. תודה רבה לכל השותפים ביצירת התוכן ב-Chromium וב-Intel ובמיוחד אחרים, שעזרו לבצע את המשימה.

כעת נסתכל על כמה מהתרחישים המעולים ש-WebGPU מאפשר.

ביטול הנעילה של עומסי עבודה (workloads) חדשים של GPU לעיבוד

תכונות WebGPU, כמו מפענחי מחשבים (shader), מאפשרות העברה של סוגים חדשים של אלגוריתמים ב-GPU. לדוגמה, אלגוריתמים שיכולים להוסיף עוד פרטים דינמיים לסצנות, לדמות תופעות פיזיקליות ועוד. יש אפילו עומסי עבודה שבעבר אפשר היה לבצע רק ב-JavaScript. עכשיו אפשר להעביר אותם ל-GPU.

בסרטון הבא מוצג האלגוריתם של הקוביות הצועדות שמשמש לכוונון לפני השטח של המטא-בולים האלה. ב-20 השניות הראשונות של הסרטון, האלגוריתם, כאשר הוא רץ ב-JavaScript, מתקשה לעמוד בקצב של הרצת הדף רק ב-8 FPS, וכתוצאה מכך נוצרת אנימציה מקפיצה. כדי לשמור על ביצועים טובים ב-JavaScript, נצטרך להוריד הרבה את רמת הפרטים.

מדובר בהפרש של יום ולילה כאשר אנו מעבירים את אותו אלגוריתם להצללה (shader) חישוב, שמוצג בסרטון לאחר 20 שניות. הביצועים משתפרים באופן משמעותי כי עכשיו הדף פועל בקצב חלק של 60 FPS, ועדיין יש הרבה פוטנציאל לשיפור הביצועים עבור אפקטים אחרים. בנוסף, לולאת ה-JavaScript הראשית בדף התפנה לחלוטין לביצוע משימות אחרות, מה שמבטיח שהאינטראקציות עם הדף ימשיכו להגיב.

ההדגמה של מטא-בול

WebGPU גם מאפשר אפקטים חזותיים מורכבים שלא היו שימושיים לפני כן. בדוגמה הבאה, שנוצרה בספרייה הפופולרית Babylon.js, פני השטח באוקיינוס עוברים סימולציה מלאה של ה-GPU. הדינמיקה המציאותית נוצרת מגלים עצמאיים רבים שנוספים זה לזה. אבל סימולציה של כל גל באופן ישיר תהיה יקרה מדי.

הדגמה של האוקיינוס

זו הסיבה לכך שבהדגמה נעשה שימוש באלגוריתם מתקדם שנקרא Fast Forier Transform. במקום לייצג את כל הגלים כנתוני מיקום מורכבים, נעשה שימוש בנתונים הספקטרליים, שהם יעילים הרבה יותר לביצוע חישובים. לאחר מכן כל מסגרת משתמשת בטרנספורמציה פורייה כדי להמיר מנתונים ספקטרליים לנתוני המיקום שמייצגים את גובה הגלים.

מסקנה מהירה יותר בלמידת מכונה

WebGPU גם עוזרת להאיץ את למידת המכונה, שהפכה לשימוש עיקרי ב-GPU בשנים האחרונות.

מזה זמן רב, מפתחי קריאייטיב משתמשים בממשק ה-API לעיבוד של WebGL כדי לבצע פעולות שלא קשורות לעיבוד, כמו חישובים של למידת מכונה. עם זאת, לשם כך צריך לשרטט את הפיקסלים של משולשים כדרך לבצע את החישובים, ולארוז ולפרוס בקפידה נתוני tensor במרקם, במקום להשתמש בגישה כללית יותר לזיכרון.

איור של חוסר היעילות בפעולה יחידה של למידת מכונה באמצעות WebGL, כולל עומסי זיכרון מיותרים, חישובים מיותרים ומעט ערכים שכתובים בכל שרשור.
הפעלה של מפעיל ML אחד באמצעות WebGL.

שימוש ב-WebGL בצורה כזו מחייב מפתחים להתאים את הקוד שלהם באופן מוזר לציפיות של ממשק API שמיועד רק לציור. בשילוב עם היעדר תכונות בסיסיות כמו גישה משותפת לזיכרון בין חישובים, עבודה כפולה וביצועים לא אופטימליים.

תוכנות הצללה (shader) של Compute הן התכונה החדשה העיקרית של WebGPU, ולהסיר את הבעיות האלה. תוכנות הצללה של Compute מציעות מודל תכנות גמיש יותר שמנצל את האופי המקביל באופן מסיבי של ה-GPU, מבלי להיות מוגבל על ידי המבנה המחמיר של פעולות העיבוד.

יתרונות היעילות השונים בהצללה (shader) של מחשוב WebGPU, כולל עומסי זיכרון משותפים, חישובים משותפים וכתיבה גמישה בזיכרון.
נעילות של תוכנת הצללה (shader) למחשוב WebGPU.

תוכנות הצללה (shader) מחשוב מעניקים יותר הזדמנויות לשיתוף נתונים ותוצאות חישוב בתוך קבוצות של תוכנות הצללה (shader) לשיפור היעילות. כך ניתן להשיג רווחים משמעותיים לעומת ניסיונות קודמים להשתמש ב-WebGL לאותה מטרה.

כדוגמה לשיפור היעילות שאפשר להשיג, יציאה ראשונית של מודל דיפוזיה של תמונה ב-TensorFlow.js מציגה שיפור ביצועים פי 3 במגוון חומרה כשעוברים מ-WebGL ל-WebGPU. בחלק מהחומרה שנבדקה, התמונה עובדה תוך פחות מ-10 שניות. בגלל שזו הייתה יציאה מוקדמת, אנחנו מאמינים שאפשר לשפר עוד יותר ב-WebGPU וב-TensorFlow.js. כדאי לקרוא את המאמר מה חדש ב-Web ML ב-2023? שיחת Google I/O.

עם זאת, WebGPU לא רק נועד להביא תכונות GPU לאינטרנט.

האפליקציה מיועדת קודם ל-JavaScript

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

WebGPU פותחו עם יתרון של שיפוט של מפתחים במשך יותר מעשור, שעושים עבודה מדהימה עם WebGL. הצלחנו לקחת את הבעיות שהם נתקלו בהן, את צווארי הבקבוק שבהם הם נתקלו ואת הבעיות שהם העלו והעלו את כל המשובים האלה אל ה-API החדש.

ראינו שמודל המצב הגלובלי של WebGL הפך את היצירה של ספריות ואפליקציות חזקות וקומפוזביליות לקשה ולשביר. לכן, WebGPU מפחיתה באופן משמעותי את כמות המצבים שעליהם מפתחים צריכים לעקוב בזמן שהם שולחים את פקודות ה-GPU.

שמענו שניפוי באגים באפליקציות WebGL היה כואב, לכן WebGPU כולל מנגנוני טיפול בשגיאות גמישים יותר שלא משפיעים על הביצועים שלכם. עם זאת, עשינו מאמצים רבים כדי להבטיח שכל הודעה שתשלחו דרך ה-API תהיה קלה להבנה ולפעולה בהתאם.

כמו כן, גילינו שלעיתים קרובות התקורה של ביצוע קריאות רבות מדי של JavaScript הייתה צוואר בקבוק באפליקציות WebGL מורכבות. כתוצאה מכך, ה-WebGPU API פחות צ'אטי, כך שתוכלו להשיג יותר בעזרת פחות קריאות לפונקציה. אנחנו מתמקדים בביצוע אימותים כבדים מראש, כדי שלולאת השרטוט הקריטית תהיה "רזה" ככל האפשר. אנחנו גם מציעים ממשקי API חדשים, כמו Render Bundles, שמאפשרים להקליט מראש מספר גדול של פקודות ציור ולהפעיל אותן מחדש בהפעלה אחת.

כדי להמחיש את ההבדל הדרמטי שתכונה כמו חבילות עיבוד תמונה יכולה לעשות, הנה הדגמה נוספת מ-Babylon.js. הכלי שלהם לעיבוד WebGL 2 יכול להריץ את כל הקריאות של JavaScript כדי לעבד את הסצנה של גלריית האומנות בערך 500 פעמים בשנייה. וזה די טוב!

גלריית האומנות

עם זאת, כלי הרינדור WebGPU שלהם מפעיל תכונה שהם מכנים 'עיבוד snapshot'. התכונה הזו, שנוצרה על גבי חבילות עיבוד של WebGPU, מאפשרת לשלוח את אותה סצנה מהר יותר מפי 10. התקורה שתצטמצם באופן משמעותי מאפשרת ל-WebGPU לעבד סצנות מורכבות יותר, ובמקביל לאפשר לאפליקציות לעשות יותר עם JavaScript במקביל.

לממשקי API של גרפיקה מודרנית יש מוניטין של מורכבות, פשטות מסחר שמציעה הזדמנויות קיצוניות לאופטימיזציה. מצד שני, WebGPU ממוקד בתאימות בין פלטפורמות שונות, ומטפל באופן אוטומטי בנושאים רגילים, כמו סנכרון משאבים, ברוב המקרים.

לכך יש את תופעת הלוואי המשמחת שקל ללמוד ולהשתמש ב-WebGPU. הוא מסתמך על תכונות קיימות של פלטפורמת האינטרנט לדברים כמו טעינת תמונות וסרטונים, ונשען על דפוסי JavaScript ידועים כמו הבטחות לפעולות אסינכרוניות. כך ניתן להפחית את הכמות הנדרשת של קוד סטנדרטי (בוילרפלייט). אפשר להציג את המשולש הראשון בפחות מ-50 שורות קוד.

<canvas id="canvas" width="512" height="512"></canvas>
<script type="module">
  const adapter = await navigator.gpu.requestAdapter();
  const device = await adapter.requestDevice();

  const context = canvas.getContext("webgpu");
  const format = navigator.gpu.getPreferredCanvasFormat();
  context.configure({ device, format });

  const code = `
    @vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
      @builtin(position) vec4f {
       const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
       return vec4f(pos[i], 0, 1);
    }
    @fragment fn fragmentMain() -> @location(0) vec4f {
      return vec4f(1, 0, 0, 1);
    }`;
  const shaderModule = device.createShaderModule({ code });
  const pipeline = device.createRenderPipeline({
    layout: "auto",
    vertex: {
      module: shaderModule,
      entryPoint: "vertexMain",
    },
    fragment: {
      module: shaderModule,
      entryPoint: "fragmentMain",
      targets: [{ format }],
    },
  });
  const commandEncoder = device.createCommandEncoder();
  const colorAttachments = [
    {
      view: context.getCurrentTexture().createView(),
      loadOp: "clear",
      storeOp: "store",
    },
  ];
  const passEncoder = commandEncoder.beginRenderPass({ colorAttachments });
  passEncoder.setPipeline(pipeline);
  passEncoder.draw(3);
  passEncoder.end();
  device.queue.submit([commandEncoder.finish()]);
</script>

סיכום

מרגש לראות את כל האפשרויות החדשות ש-WebGPU מציע לפלטפורמת האינטרנט, ואנחנו מצפים לראות את כל תרחישי השימוש החדשים והמגניבים שתמצאו ב-WebGPU!

סביבה עסקית תוססת של ספריות ומסגרות נבנתה סביב WebGL, ואותה סביבה עסקית משתוקקת לאמץ את WebGPU. התמיכה ב-WebGPU מתבצעת או שכבר הושלמה בספריות פופולריות רבות של JavaScript WebGL. במקרים מסוימים, ניצול היתרונות של WebGPU עשוי להיות פשוט כמו שינוי דגל יחיד.

Babylon.js, Construct 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js ו-Unity.
מסגרות, אפליקציות וספריות עם יציאות WebGPU בסיום או פעילות.

והגרסה הראשונה הזו ב-Chrome 113 היא רק התחלה. למרות שהגרסה הראשונית שלנו מיועדת ל-Windows, ל-ChromeOS ול-MacOS, אנחנו מתכננים להשיק את WebGPU בשאר הפלטפורמות, כמו Android ו-Linux בעתיד הקרוב.

ולא מדובר רק בצוות Chrome שכבר עובד על השקת WebGPU. ההטמעה מתבצעת גם ב-Firefox וב-WebKit.

בנוסף, תכונות חדשות כבר מתוכננות ב-W3C שניתן לחשוף אותן כאשר יהיו זמינות בחומרה. לדוגמה: ב-Chrome אנחנו מתכננים להפעיל בקרוב תמיכה במספרי נקודות צפות של 16 ביט בתוכנות הצללה (shader) ובסיווג ההוראות DP4a, כדי לשפר עוד יותר את הביצועים של למידת המכונה.

WebGPU הוא ממשק API נרחב שמאפשר ביצועים מדהימים אם משקיעים בו. היום אנחנו יכולים לתאר את היתרונות שלו רק ברמה גבוהה, אבל אם אתם רוצים להתחיל להשתמש ב-WebGPU, מומלץ לנסות את Codelab במבוא, אפליקציית WebGPU הראשונה שלכם. ב-Codelab הזה תיצרו גרסת GPU של משחק החיים הקלאסי של קונווי. ב-Codelab הזה נדריך אתכם בתהליך שלב אחר שלב, כדי שתוכלו לנסות אותו גם אם זו הפעם הראשונה שאתם מפתחים את ה-GPU.

כדאי גם להכיר את הדוגמאות של WebGPU כדי לקבל מושג לגבי ה-API. המשולשים האלה נעים בין "משולש השלום" המסורתי ועד לעיבוד וחישוב צינורות עיבוד נתונים מלאים יותר, תוך הדגמה של מגוון טכניקות. לבסוף, מומלץ לעיין במשאבים האחרים שלנו.