איך 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.
מקבלים גישה לעומסי עבודה חדשים של GPU לעיבוד
תכונות של WebGPU, כמו תוכנות הצללה (shader) במחשוב, מאפשרות לנייד סוגים חדשים של אלגוריתמים ב-GPU. לדוגמה, אלגוריתמים שיכולים להוסיף פרטים דינמיים יותר לזירות, לדמות תופעות פיזיות ועוד. יש אפילו עומסי עבודה שקודם אפשר היה לבצע רק ב-JavaScript, ועכשיו אפשר להעביר אותם ל-GPU.
בסרטון הבא מוצג האלגוריתם marching cubes שמשמש ליצירת משולשויות על פני השטח של המטא-כדורים האלה. ב-20 השניות הראשונות של הסרטון, כשהאלגוריתם פועל ב-JavaScript, הוא מתקשה לעמוד בקצב של הדף שפועל במהירות של 8 פריימים לשנייה בלבד, וכתוצאה מכך התנועה באנימציה קטועה. כדי לשמור על ביצועיו ב-JavaScript, עלינו להוריד באופן משמעותי את רמת הפרטים.
כשאנחנו מעבירים את אותו אלגוריתם להצללה של מחשוב, שניתן לראות בסרטון לאחר 20 שניות, מדובר בהפרש של לילה ויום. הביצועים השתפרו באופן משמעותי, והדף פועל עכשיו במהירות חלקה של 60FPS, ועדיין יש הרבה מקום לביצועים טובים יותר עם אפקטים אחרים. בנוסף, לולאת ה-JavaScript הראשית של הדף פנויה לחלוטין למשימות אחרות, מה שמבטיח שהאינטראקציות עם הדף יישארו רספונסיביות.
WebGPU מאפשר גם להשתמש באפקטים חזותיים מורכבים שלא היו מעשיים בעבר. בדוגמה הבאה, שנוצרה בספרייה הפופולרית Babylon.js, מדמה את פני האוקיינוס לגמרי ב-GPU. הדינמיקה הריאליסטית נוצרת מהרבה גלים עצמאיים שנוספים זה לזה. אבל סימולציה של כל גל באופן ישיר תהיה יקרה מדי.
לכן, הדגמה משתמשת באלגוריתם מתקדם שנקרא Fast Fourier Transform. במקום לייצג את כל הגלים כנתוני מיקום מורכבים, המערכת משתמשת בנתונים הספקטרליים, שמאפשרים לבצע חישובים בצורה יעילה הרבה יותר. לאחר מכן, בכל פריים נעשה שימוש בטרנספורמציית Fourier כדי להמיר מנתונים ספקטרליים לנתוני מיקום שמייצגים את גובה הגלים.
הסקת מסקנות מהירה יותר בלמידת מכונה
WebGPU שימושי גם כדי לזרז למידת מכונה, שהפכה לשימוש העיקרי ב-GPU בשנים האחרונות.
במשך זמן רב, מפתחים יצירתיים השתמשו ב-API לעיבוד של WebGL למטרות אחרות, כמו ביצוע פעולות שלא קשורות לעיבוד, כמו חישובים של למידת מכונה. עם זאת, כדי לעשות זאת צריך לצייר את הפיקסלים של המשולשים כדי להתחיל את החישובים, ולקפל ולפרוק בזהירות את נתוני הטנסור בטקסטורה במקום לבצע גישה לזיכרון למטרות כלליות יותר.
כדי להשתמש ב-WebGL בדרך הזו, המפתחים צריכים להתאים את הקוד שלהם בצורה לא נוחה לציפיות של ממשק API שמיועד רק לציור. בשילוב עם חוסר התכונות הבסיסיות כמו גישה לזיכרון משותף בין חישובים, המצב הזה מוביל לעבודה כפולה ולביצועים לא אופטימליים.
עיבוד שגיאות (compute shaders) הוא התכונה החדשה העיקרית של WebGPU, והוא מסיר את נקודות החולשה האלה. תוכנות הצללה למחשוב מציעים מודל תכנות גמיש יותר שמנצל את האופי המקביל המדהים של ה-GPU כשהוא לא מוגבל על ידי המבנה המחמיר של פעולות רינדור.
תוכנות הצללה (shader) של מחשוב נותנת יותר הזדמנות לשיתוף נתונים ותוצאות חישוב בתוך קבוצות של תוכנות הצללה (shader). השימוש ב-WebGL יכול להוביל לשיפורים משמעותיים בהשוואה לניסיונות קודמים להשתמש ב-WebGL לאותה מטרה.
דוגמה לשיפור היעילות שאפשר להשיג: העברה של מודל ראשוני של דיפוזיה של תמונה ב-TensorFlow.js מ-WebGL ל-WebGPU מובילה לשיפור של פי 3 בביצועים במגוון חומרות. בחלק מחומרת הבדיקה, התמונה עברה רינדור תוך פחות מ-10 שניות. וכיוון שזו הייתה גרסה מוקדמת, אנחנו מאמינים שאפשר לבצע עוד שיפורים ב-WebGPU וב-TensorFlow.js. מה חדש ב-Web ML בשנת 2023? סשן ב-Google I/O.
אבל WebGPU לא משפיע רק על שימוש בתכונות של GPU באינטרנט.
תוכנן בראש ובראשונה ל-JavaScript
התכונות שמאפשרות תרחישים לדוגמה כאלה זמינים כבר זמן מה למפתחים ספציפיים לפלטפורמה מסוימת במחשב ובנייד, והאתגר שלנו היה לחשוף אותם באופן שנראה כמו חלק טבעי מפלטפורמת האינטרנט.
WebGPU פותח על סמך ניסיון של יותר מעשור של מפתחים שעשו עבודה מדהימה עם WebGL. הצלחנו לקחת את הבעיות שהם נתקלו בהן, את צווארי הבקבוק שבהם הן נתקלו, ואת הבעיות שהם העלו והועברו לכל המשוב הזה לתוך ה-API החדש.
הבנו שמודל המצב הגלובלי של WebGL מקשה על יצירת ספריות ואפליקציות חזקות וניתנות לשימוש חוזר, וגם הופך אותן לפגיעות. בצורה הזו, WebGPU מפחית משמעותית את כמות המצב שהמפתחים צריכים לעקוב אחריהם בזמן שליחת פקודות ה-GPU.
קיבלנו משוב על כך שדיבוג של אפליקציות WebGL הוא תהליך קשה, ולכן WebGPU כולל מנגנונים גמישים יותר לטיפול בשגיאות שלא פוגעים בביצועים. בנוסף, עשינו מאמצים רבים כדי לוודא שכל הודעה שתקבלו מה-API תהיה קלה להבנה וניתן יהיה לבצע בה פעולות.
גילינו גם שלעיתים קרובות, העלויות הנלוות ליצירת יותר מדי קריאות ל-JavaScript הן צוואר בקבוק באפליקציות WebGL מורכבות. כתוצאה מכך, ה-API של WebGPU פחות מדבר, כך שתוכלו להשיג יותר עם פחות קריאות לפונקציות. אנחנו מתמקדים בביצוע תיקוף של נתונים כבדים מראש, כדי לשמור על לולאת משיכה קריטית קטנה ככל האפשר. בנוסף, אנחנו מציעים ממשקי API חדשים כמו Render Bundles, שמאפשרים להקליט מראש מספר גדול של פקודות ציור ולנגן אותן מחדש בקריאה אחת.
כדי להמחיש את ההבדל הדרמטי שיכולה לעשות תכונה כמו חבילות רינדור, הנה הדגמה נוספת של Babylon.js. המרת ה-WebGL 2 יכולה לבצע את כל הקריאות ל-JavaScript כדי להציג את הסצנה של גלריית האמנות כ-500 פעמים בשנייה. זה נתון די טוב!
עם זאת, ה-renderer של WebGPU מאפשר תכונה שנקראת 'רינדור של קובץ snapshot'. התכונה הזו מבוססת על חבילות רינדור של WebGPUs, ומאפשרת לשלוח את אותה סצנה במהירות גבוהה פי 10. הפחתת העלויות הנלוות באופן משמעותי מאפשרת ל-WebGPU ליצור עיבוד תמונה של סצנות מורכבות יותר, וגם מאפשרת לאפליקציות לבצע יותר פעולות ב-JavaScript במקביל.
לממשקי API מודרניים של גרפיקה יש מוניטין של מורכבות, והם מחליפים את הפשטות בהזדמנויות אופטימיזציה קיצוניות. לעומת זאת, WebGPU מתמקד בתאימות לפלטפורמות שונות, ומטפל באופן אוטומטי בנושאים מסורתיים כמו סנכרון משאבים, ברוב המקרים.
לכך יש השפעה חיובית: קל ללמוד את WebGPU ולהשתמש בו. התג מסתמך על תכונות קיימות בפלטפורמת האינטרנט לפעולות כמו טעינה של תמונות וסרטונים, ומשתמש בתבניות JavaScript מוכרות כמו Promises לפעולות אסינכרוניות. כך כדאי לשמור על הכמות המינימלית של הקוד הסטנדרטי. אפשר להציג את המשולש הראשון במסך שמכיל פחות מ-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 מתבצעת או כבר הושלמה בספריות WebGL פופולריות רבות של Javascript, ובמקרים מסוימים ליהנות מהיתרונות של WebGPU יכול להיות פשוט כמו שינוי דגל אחד.
הגרסה הראשונה ב-Chrome 113 היא רק ההתחלה. הגרסה הראשונית שלנו מיועדת ל-Windows, ל-ChromeOS ול-macOS, אבל אנחנו מתכננים להוסיף את WebGPU לפלטפורמות הנותרות, כמו Android ו-Linux, בעתיד הקרוב.
וגם לא רק צוות Chrome עבד על השקת WebGPU. ההטמעה מתבצעת גם ב-Firefox וב-WebKit.
בנוסף, תכונות חדשות כבר מתוכננות ב-W3C וניתן לחשוף אותן כאשר הן זמינות בחומרה. לדוגמה: בקרוב אנחנו מתכננים להפעיל ב-Chrome תמיכה במספרים של 16 ביט עם נקודה צפה בשיידרים ואת סוג ההוראות DP4a, כדי לשפר עוד יותר את הביצועים של למידת המכונה.
WebGPU הוא ממשק API מקיף שמעניק ביצועים מדהימים אם משקיעים בו. היום נוכל לתאר את היתרונות שלו ברמה גבוהה בלבד, אבל אם אתם רוצים להתחיל להשתמש ב-WebGPU, כדאי לכם לנסות את Codelab ההיכרות שלנו, אפליקציית WebGPU הראשונה שלך. ב-Codelab הזה תיצרו גרסת GPU של משחק החיים הקלאסי של Conway. ב-codelab הזה נסביר את התהליך שלב אחרי שלב, כדי שתוכלו לנסות אותו גם אם זו הפעם הראשונה שאתם מפתחים ל-GPU.
הדוגמאות ל-WebGPU הן גם מקום טוב לקבל מושג על ה-API. הדוגמאות נעות בין 'משולש שלום' הפשוט לבין צינורות עיבוד נתונים מלאים יותר לעיבוד וחישוב, שממחישים מגוון שיטות. לסיום, תוכלו להיעזר במקורות המידע האחרים שלנו.