שרשורי WebAssembly מוכנים לניסיון ב-Chrome 70

התמיכה ב-thread WebAssembly נשלחה ל-Chrome 70 במסגרת תקופת ניסיון מקורית.

Alex Danilo

בעזרת WebAssembly (Wasm), אפשר לאסוף קוד שנכתב ב-C++ ובשפות אחרות כדי להריץ אותו באינטרנט. תכונה שימושית מאוד באפליקציות מקוריות היא היכולת להשתמש ב-threads – פרימיטיבית לחישוב מקביל. רוב מפתחי C ו-C++ יכירו את pthreads, שהוא API סטנדרטי לניהול שרשורים באפליקציות.

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

גרסת Chrome 70 תומכת בשרשורים עבור WebAssembly, ואנחנו מעודדים מפתחים שרוצים להתחיל להשתמש בהם ולתת לנו משוב.

שרשורים? מה לגבי Workers?

הדפדפנים תומכים במקבילות באמצעות Web Workers מאז 2012 ב-Chrome 4; למעשה זה נורמלי לשמוע מונחים כמו'ב-thread הראשי ' וכו'. עם זאת, עובדי אינטרנט לא משתפים ביניהם נתונים שניתנים לשינוי, אלא מסתמכים על העברת הודעות לצורך תקשורת. למעשה, Chrome מקצה מנוע V8 חדש לכל אחד מהם (שנקרא 'בודד'). הוא מבודד לא קוד מקומפל או אובייקטים של JavaScript, ולכן הוא לא יכול לשתף נתונים שניתנים לשינוי כמו pthreads.

לעומת זאת, שרשורי WebAssembly הם שרשורים שיכולים לשתף את אותו זיכרון Wasm. האחסון הבסיסי של הזיכרון המשותף נוצר באמצעות SharedArrayBuffer, פרימיטיב של JavaScript שמאפשר לשתף תוכן של ArrayBuffer אחד בו-זמנית בין עובדים. כל שרשור WebAssembly פועל ב-Web Worker, אבל זיכרון Wasm המשותף שלו מאפשר להם לעבוד ממש כמו בפלטפורמות מקוריות. כלומר, האפליקציות שמשתמשות בשרשורי Wasm אחראיות לניהול הגישה לזיכרון המשותף, כמו בכל אפליקציה רגילה עם חלוקה לשרשורים. יש הרבה ספריות קוד קיימות שכתובות ב-C או ב-C++ שמשתמשות ב-pthreads. אפשר להדר אותן ל-Wasm ולפעול במצב Threaded true כדי לאפשר ליותר ליבות לעבוד על אותם נתונים בו-זמנית.

דוגמה פשוטה

דוגמה לתוכנית C פשוטה שמשתמשת בשרשורים.

#include <pthread.h>
#include <stdio.h>

// Calculate Fibonacci numbers shared function
int fibonacci(int iterations) {
    int     val = 1;
    int     last = 0;

    if (iterations == 0) {
        return 0;
    }
    for (int i = 1; i < iterations; i++) {
        int     seq;

        seq = val + last;
        last = val;
        val = seq;
    }
    return val;
}
// Start function for the background thread
void *bg_func(void *arg) {
    int     *iter = (void *)arg;

    *iter = fibonacci(*iter);
    return arg;
}
// Foreground thread and main entry point
int main(int argc, char *argv[]) {
    int         fg_val = 54;
    int         bg_val = 42;
    pthread_t   bg_thread;

    // Create the background thread
    if (pthread_create(&bg_thread, NULL, bg_func, &bg_val)) {
        perror("Thread create failed");
        return 1;
    }
    // Calculate on the foreground thread
    fg_val = fibonacci(fg_val);
    // Wait for background thread to finish
    if (pthread_join(bg_thread, NULL)) {
        perror("Thread join failed");
        return 2;
    }
    // Show the result from background and foreground threads
    printf("Fib(42) is %d, Fib(6 * 9) is %d\n", bg_val, fg_val);

    return 0;
}

הקוד מתחיל בפונקציה main() שמצהירה על שני משתנים fg_val ו-bg_val. יש גם פונקציה בשם fibonacci(), שתיקרא על ידי שני ה-threads בדוגמה הזו. הפונקציה main() יוצרת שרשור ברקע באמצעות pthread_create(), שהמשימה שלה היא לחשב את ערך הרצף של מספרי פיבונאצ'י שתואם לערך של המשתנה bg_val. בינתיים, הפונקציה main() שפועלת ב-thread בחזית מחשבת אותה עבור המשתנה fg_val. בסיום ההפעלה של שרשור הרקע, התוצאות מודפסות.

הידור לתמיכה בשרשור

קודם כל, צריך להתקין את emscripten SDK, עדיף בגרסה 1.38.11 ואילך. כדי ליצור את הקוד לדוגמה עם threads מופעלים להרצה בדפדפן, אנחנו צריכים להעביר כמה סימונים נוספים ל-emscript emcc מהדר. שורת הפקודה שלנו נראית כך:

emcc -O2 -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=2 -o test.js test.c

הארגומנט של שורת הפקודה '-s USE_PTHREADS=1' מפעיל תמיכה בשרשורים במודול WebAssembly שעבר הידור, והארגומנט '-s PTHREAD_POOL_SIZE=2' מורה מהדר ליצור מאגר של שני (2) שרשורים.

כשהתוכנית פועלת, המערכת טוענת את המודול של WebAssembly, יוצרים Web Worker לכל אחד מהשרשורים במאגר השרשורים, משתפים את המודול עם כל אחד מהעובדים. במקרה הזה הוא 2 והוא ישמש בכל פעם שתתבצע קריאה ל-pthread_create(). כל אחד מהעובדים יוצר מופע של מודול Wasm עם אותו זיכרון, וכך מאפשר להם לשתף פעולה. השינויים החדשים ביותר ב-V8 בגרסה 7.0 חולקים את הקוד המקורי המורכב של מודולי Wasm שמועברים בין עובדים, וכך מאפשר להתאים גם אפליקציות גדולות מאוד לעובדים רבים. הערה: כדאי לוודא שגודל מאגר השרשורים שווה למספר השרשורים המקסימלי שהאפליקציה צריכה, אחרת יכול להיות שיצירת השרשור תיכשל. במקביל, אם מאגר השרשורים גדול מדי, אתם יוצרים עובדי אינטרנט מיותרים שלא יעשו שום דבר מלבד שימוש בזיכרון.

איך לנסות את זה

הדרך המהירה ביותר לבדוק את המודול WebAssembly היא להפעיל את התמיכה בשרשורי WebAssembly הניסיוני ב-Chrome 70 ואילך. מנווטים לכתובת ה-URL about://flags בדפדפן באופן הבא:

דף הדגלים של Chrome

בשלב הבא, מוצאים את ההגדרה הניסיונית של שרשורי WebAssembly שנראית כך:

הגדרת שרשורים של WebAssembly

שנו את ההגדרה למופעל כפי שמוצג למטה, ולאחר מכן הפעילו מחדש את הדפדפן.

הגדרת השרשורים של WebAssembly הופעלה

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

<!DOCTYPE html>
<html>
  <title>Threads test</title>
  <body>
    <script src="test.js"></script>
  </body>
</html>

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

פלט המסוף מתוכנית פיבונאצ&#39;י

תוכנית WebAssembly עם השרשורים בוצעה בהצלחה! אנחנו ממליצים לכם לנסות אפליקציה משלכם עם שרשור לפי השלבים שמפורטים למעלה.

בדיקה בשטח עם גרסת מקור לניסיון

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

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

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

אם תרצו לראות מה אפשר לעשות בעזרת 4 שרשורים שפועלים במקביל בגרפיקה של ASCII, כדאי גם לצפות בהדגמה הזו.

נשמח לקבל ממך משוב

שרשורי WebAssembly הם פרימיטיב חדש ושימושי מאוד לניוד אפליקציות לאינטרנט. עכשיו אפשר להריץ אפליקציות וספריות מסוג C ו-C++ שמחייבות תמיכה ב-pthreads בסביבת WebAssembly.

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