מה זה PTX - שפת הביניים שמחברת בין הקוד שלכם לחומרה¶
כשמדובר על שפת אסמבלי מוסברת, בדרך כלל מדברים על שפה שממופה ישירות לחומרה ספציפית. אבל ב-CUDA יש שכבה נוספת באמצע, שמאפשרת דבר מעניין - קוד שנכתב היום יכול לרוץ על GPU שעוד לא יצא לשוק. השכבה הזו נקראת PTX, ובלעדיה כל אקוסיסטם ה-CUDA היה נראה אחרת לגמרי.
אז מה זה בעצם PTX¶
PTX, ראשי תיבות של Parallel Thread Execution, היא שפת ביניים - virtual instruction set architecture. כשאתם מקמפלים קוד CUDA עם nvcc, הוא לא הופך ישירות לקוד מכונה שרץ על החומרה. במקום זה, הוא עובר קודם לPTX, ורק אחר כך, בשלב נפרד, PTX הופך לקוד מכונה אמיתי שנקרא SASS, שמתאים לארכיטקטורת החומרה הספציפית שעליה הוא רץ.
הרעיון דומה במידה מסוימת לbytecode בשפות כמו Java. PTX היא לא קוד מכונה אמיתי של אף שבב ספציפי, היא ייצוג מופשט יותר, "וירטואלי", של ההוראות שהתוכנית צריכה לבצע.
למה בכלל צריך שכבה נוספת¶
הסיבה המרכזית היא תאימות קדימה - forward compatibility. NVIDIA מוציאה ארכיטקטורות GPU חדשות כל כמה שנים, וכל אחת מהן יכולה לכלול שינויים בקוד המכונה בפועל. אם קוד CUDA היה מתקמפל ישירות לקוד מכונה של החומרה הקיימת, הוא לא היה בהכרח רץ על חומרה עתידית שעוד לא הייתה קיימת בזמן הקומפילציה.
הפתרון הוא ש-PTX נשמרת בתוך הקובץ הבינארי לצד קוד ה-SASS, וברגע שהתוכנית רצה על מחשב עם דרייבר NVIDIA, הדרייבר עצמו יודע לקחת את הPTX ולקמפל אותה, just-in-time, לקוד מכונה שמתאים בדיוק ל-GPU שמותקן במחשב הזה, גם אם הוא יצא לשוק אחרי שהתוכנית נכתבה. זה בדיוק המנגנון שמאפשר לתוכנות ישנות להמשיך לרוץ, ולפעמים אפילו להיות מהירות יותר, על כרטיסי מסך חדשים.
מה יש בפועל בתוך PTX¶
אם פותחים קובץ PTX, רואים משהו שדומה מאוד לאסמבלי - הוראות טקסטואליות קריאות, עם רגיסטרים וירטואליים ולא רגיסטרים פיזיים אמיתיים. זה עדיין הרבה יותר נמוך רמה מקוד C או C++ שכתבתם, אבל הוא עדיין לא הצורה הסופית שרצה בפועל על השבב. מספר הרגיסטרים הווירטואליים, למשל, לא בהכרח משקף את מספר הרגיסטרים הפיזיים שיוקצו בפועל - זה נקבע רק בשלב הקומפילציה מPTX לSASS.
מתי מתכנתים בכלל נתקלים בזה¶
רוב מתכנתי CUDA לא צריכים לקרוא או לכתוב PTX ידנית ביום-יום. אבל להבין שהיא קיימת חשוב מכמה סיבות. ראשית, זה מסביר תופעה שמבלבלת מתחילים - למה קובץ בינארי אחד יכול לרוץ על כמה דורות שונים של GPU. שנית, כלים לניתוח ביצועים מתקדמים לפעמים מציגים PTX כשלב ביניים, ולפעמים מתכנתים שרוצים שליטה ממש עדינה כותבים inline PTX בתוך קוד CUDA, בדומה לאיך שכותבים inline assembly בשפות אחרות למקרים נדירים שדורשים שליטה מוחלטת.
המקום שלה בשרשרת הכלים¶
PTX היא בדיוק האמצע בין הקוד ברמה גבוהה שאתם כותבים לבין SASS, קוד המכונה האמיתי שרץ על השבב. הבנת שני השלבים האלה ביחד נותנת תמונה מלאה של מה בדיוק קורה לקוד שלכם מהרגע שכתבתם אותו ועד הרגע שהוא באמת רץ על אלפי ליבות חומרה.
זה בדיוק סוג התמונה המלאה שאנחנו בונים בקורס תכנות GPU - לא רק איך כותבים CUDA, אלא מה קורה מתחת למכסה המנוע בדרך לחומרה.
לסיכום¶
PTX היא שפת הביניים הווירטואלית שמאפשרת ל-CUDA לתמוך בדורות עתידיים של חומרה בלי שהמתכנת יצטרך לדעת מראש בדיוק על איזה שבב הקוד ירוץ. היא לא הצעד האחרון בדרך לחומרה, אבל בלעדיה, כל האקוסיסטם של תאימות בין דורות GPU היה נראה הרבה יותר שביר.
בואו תבינו את כל השכבות שקוד שלכם עובר, עם קהילה שכבר שם.