לדלג לתוכן

זיכרון קבוע וטקסטורה ב-GPU - הזיכרונות הייעודיים שרוב המתחילים מפספסים

בפוסט על היררכיית הזיכרון ב-GPU עברנו על רגיסטרים, shared memory, cache וזיכרון גלובלי. אבל יש עוד שני סוגי זיכרון ב-CUDA שלא מדברים עליהם מספיק, ושבמצבים הנכונים יכולים לשפר ביצועים בצורה דרמטית - זיכרון קבוע וזיכרון טקסטורה.

זיכרון קבוע - constant memory

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

היתרון של constant memory נובע ממנגנון חומרה מיוחד שנקרא broadcast. כשכל ה-threads בתוך warp קוראים בדיוק את אותה כתובת בזיכרון קבוע, החומרה יכולה לשלוח את הערך לכולם בבת אחת במקום לבצע קריאה נפרדת לכל thread. יש גם cache ייעודי לזיכרון הזה, שמותאם בדיוק לדפוס הגישה הזה - אותו ערך, נקרא על ידי הרבה threads בו זמנית. כשהתנאי הזה מתקיים, הגישה לזיכרון קבוע יכולה להיות מהירה כמעט כמו קריאה מרגיסטר.

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

זיכרון טקסטורה - texture memory

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

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

מתי בכלל להשתמש בהם

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

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

חלק מארגז הכלים המלא

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

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

לסיכום

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

בואו תכירו את כל הכלים בארגז, עם קהילה שכבר שם.

הצטרפו לקהילה בדיסקורד