שיעור 23: פעולות אטומיות: atomicAdd והיסטוגרמה
כשאלפי threads מנסים לעדכן את אותו תא בזיכרון בו-זמנית, נוצר תנאי מרוץ (race condition). קחו היסטוגרמה: כל thread קורא ערך ורוצה להגדיל את המונה bins[v] באחד. הפעולה bins[v]++ נראית אטומית, אבל בפועל היא שלושה שלבים נפרדים: קריאת הערך הנוכחי, הוספת אחד, וכתיבה חזרה (read-modify-write). אם שני thread
דמיין צנצנת ספירה משותפת. בלי atomic, שני אנשים מסתכלים שהמספר 5, שניהם מוסיפים 1 בראש, ושניהם כותבים 6 — אבל היו צריכים להגיע ל-7, אז ספירה אבדה. atomic זה כמו לתת רק לאדם אחד בכל פעם להחזיק את הצנצנת, להוסיף, ולהחזיר — אף אחד לא דורך על השני.
- תנאי מרוץ (race condition)
- כששתי פעולות מקביליות ניגשות לאותו זיכרון ולפחות אחת כותבת, והתוצאה תלויה בסדר השרירותי שבו הן רצות.
- פעולה אטומית (atomic)
- פעולת read-modify-write שהחומרה מבצעת כיחידה בלתי-ניתנת-לחלוקה — אף thread אחר לא נכנס באמצע. לדוגמה atomicAdd.
- read-modify-write
- שלושת השלבים של ++: קריאת הערך, שינוי, וכתיבה חזרה. במקביל, בלי הגנה, שלבים אלה מתערבבים בין threads.
- היסטוגרמה
- ספירת כמה פעמים מופיע כל ערך. כל thread מגדיל bins[v]; ריבוי threads על אותו bin דורש atomicAdd.