כיצד המעבד וה- GPU מעבירים יחדיו גרפיקה ממוחשבת?

Aug 21, 2025
חוּמרָה

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

תמונה על ידי sskennel .

מושב השאלות והתשובות של היום מגיע אלינו באדיבות SuperUser - חלוקה משנה של Stack Exchange, קיבוץ קהילתי של אתרי שאלות ותשובות.

השאלה

קורא ה- SuperUser, סתיא, הציג את השאלה:

כאן תוכלו לראות צילום מסך של תוכנית C ++ קטנה בשם Triangle.exe עם משולש מסתובב על בסיס ממשק ה- API של OpenGL.

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

פשוט הייתי סקרן ורציתי לדעת את כל התהליך מלחיצה כפולה על Triangle.exe תחת Windows XP עד שאוכל לראות את המשולש מסתובב על הצג. מה קורה, איך מעבד CPU (שמטפל תחילה ב- .exe) ו- GPU (שמפיק סוף סוף את המשולש על המסך) מתקשרים?

אני מניח שהמעורבות בתצוגה של משולש מסתובב זה היא בעיקר החומרה / תוכנה הבאה:

חוּמרָה

  • HDD
  • זיכרון מערכת (RAM)
  • מעבד
  • זיכרון וידאו
  • GPU
  • תצוגת אל סי די

תוֹכנָה

  • מערכת הפעלה
  • ממשק API של DirectX / OpenGL
  • נהג Nvidia

מישהו יכול להסביר את התהליך, אולי בעזרת איזשהו תרשים זרימה להמחשה?

זה לא אמור להיות הסבר מורכב שמכסה כל צעד בודד (ניחוש שיחרוג מההיקף), אלא הסבר שאיש IT ביניים יכול לבצע.

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

התשובה

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

תמונה של JasonC, זמין כטפט כאן .

הוא כותב:

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

המצגת

מה נדרש כדי שהתמונה היחידה שפרסמת בשאלתך תהיה מצוירת על המסך?

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

אבל לפני שנוכל לצייר משהו, ראשית עלינו להפעיל פיגומים. נראה למה יותר מאוחר:

// נקה את המסך ואת מאגר העומק
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// אפס את מטריצת Modelview הנוכחית
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();

// ציור באמצעות משולשים
glBegin (GL_TRIANGLES);

  // אדום
  glColor3f (1.0f, 0.0f, 0.0f);
  // ראש המשולש (קדמי)
  glVertex3f (0.0f, 1.0f, 0.0f);

  // ירוק
  glColor3f (0.0f, 1.0f, 0.0f);
  // משמאל למשולש (קדמי)
  glVertex3f (-1.0f, -1.0f, 1.0f);

  // כחול
  glColor3f (0.0f, 0.0f, 1.0f);
  // Right of Triangle (חזית)
  glVertex3f (1.0f, -1.0f, 1.0f);

// בוצע ציור
glEnd ();

אז מה זה עשה?

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

  • OpenGL
  • Direct3D
  • נסים

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

ממשק זה חייב לתת לך ודאות כלים . כלים אלה מקבלים צורה של אֵשׁ שאליו אתה יכול להתקשר מהתוכנית שלך.

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

הפיגומים

לפני שתוכל באמת לבצע ציור ממשי, תצטרך לבצע להכין . עליך להגדיר את תצוגת התצוגה שלך (האזור שיוצג בפועל), את נקודת המבט שלך (את מַצלֵמָה אל תוך עולמך), באיזה אנטי כינוי תשתמש (כדי להחליק את קצוות המשולש שלך) ...

אבל אנחנו לא נסתכל על כל זה. רק נציץ בחומר שתצטרך לעשות כל פריים . כמו:

ניקוי המסך

צינור הגרפיקה לא מתכוון לנקות את המסך עבורך בכל פריים. תצטרך לספר את זה. למה? זו הסיבה לכך:

אם לא תנקה את המסך, פשוט לצייר מעל זה כל פריים. בגלל זה אנו מתקשרים glClear עם ה GL_COLOR_BUFFER_BIT מַעֲרֶכֶת. החלק השני ( GL_DEPTH_BUFFER_BIT ) אומר ל- OpenGL לנקות את עוֹמֶק בַּלָם. חיץ זה משמש לקביעת אילו פיקסלים נמצאים לפני (או מאחור) פיקסלים אחרים.

טרנספורמציה


מקור תמונה

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

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

כעת אנו משתנים פעם נוספת עם מטריצת Viewport שלנו. אנו עושים זאת בכדי לשנות את מידתנו דֶגֶם לגודל המסך שלנו. עכשיו יש לנו קבוצה של קודקודים שמוכנים להעיבד!

נחזור לטרנספורמציה קצת אחר כך.

צִיוּר

כדי לצייר משולש, אנו יכולים פשוט להורות ל- OpenGL להתחיל חדש רשימת משולשים על ידי התקשרות glBegin עם ה GL_TRIANGLES קָבוּעַ.
יש גם צורות אחרות שאתה יכול לצייר. כמו רצועת משולש או א מאוורר משולש . מדובר בעיקר באופטימיזציות, מכיוון שהם דורשים פחות תקשורת בין המעבד וה- GPU כדי לצייר את אותה כמות משולשים.

לאחר מכן, אנו יכולים לספק רשימה של קבוצות של 3 קודקודים שאמורים להרכיב כל משולש. כל משולש משתמש ב -3 קואורדינטות (כפי שאנו נמצאים במרחב תלת ממדי). בנוסף, אני גם מספק א צֶבַע לכל קודקוד, על ידי התקשרות glColor3f לפני יִעוּד glVertex3f .

הצל בין 3 הקודקודים (3 פינות המשולש) מחושב על ידי OpenGL באופן אוטומטי . זה ישלב את הצבע על פני כל המצולע.

אינטראקציה

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

זה מקבל מִגרָשׁ קשה יותר ברגע שאתה רוצה להתחיל לתקשר עם סצנת התלת מימד שלך.

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

אז איך גורמים לו לסובב?

טרנספורמציה

אני מודע לשני סוגים של טרנספורמציות המיושמים בדרך כלל:

  • טרנספורמציה מבוססת מטריקס
  • טרנספורמציה מבוססת עצם

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

דוגמא

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

אם אני רוצה לסובב אותו עכשיו, אוכל לעשות את המתמטיקה בעצמי (במעבד) ופשוט להתקשר glVertex3f עם אַחֵר קואורדינטות (שמסתובבות). או שאוכל לתת ל- GPU לעשות את כל העבודה על ידי התקשרות glRotatef לפני הציור:

// סובב את המשולש על ציר Y glRotatef (כמות, 0.0f, 1.0f, 0.0f);

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

אז רגע, מה קרה לכל שיחות המטריצה ​​קודם?

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

glRotate מייצר סיבוב של זָוִית מעלות סביב הווקטור x y z. המטריצה ​​הנוכחית (ראה glMatrixMode ) מוכפל במטריצת סיבוב כשהמוצר מחליף את המטריצה ​​הנוכחית, כאילו glMultMatrix נקראו עם המטריצה ​​הבאה כטיעון שלה:

x 2 ⁡ 1 - c + cx ⁢ y ⁡ 1 - c - z ⁢ sx ⁢ z ⁡ 1 - c + y ⁢ s 0 y ⁢ x ⁡ 1 - c + z ⁢ sy 2 ⁡ 1 - c + cy ⁢ z ⁡ 1 - c - x ⁢ s 0 x ⁢ z ⁡ 1 - c - y ⁢ sy ⁢ z ⁡ 1 - c + x ⁢ sz 2 ⁡ 1 - c + c 0 0 0 0 1

ובכן, תודה על זה!

סיכום

מה שנהיה ברור מאליו הוא, שיש הרבה דיבורים ל OpenGL. אבל זה לא מספר לָנוּ כל דבר. איפה התקשורת?

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

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

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

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

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

לאחר מכן נוכל "לעבד" את תוצאת החישוב שלנו (בצורת צבעים חדשים) למרקם חדש.

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

באמת נגענו רק בכל הנושא. תכנות גרפיקה תלת מימדית היא חיה גיהנומית.


מקור תמונה


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

תוכן כניסה . כניסה תחתונה

How To RENDER With GPU, CPU Or BOTH In Blender

CPU VS GPU: How Do They Affect Video Games?

AutoCAD Rendering With CPU Or GPU

Maya: GPU And CPU Render Tests [Arnold]

V-Ray Rendering- GPU Vs. CPU

CPU Vs GPU In Blender Rendering

GPU Vs CPU Video Rendering And Video Editing

What Is A GPU And How Does It Work? - Gary Explains

CPU Vs GPU For Video Editing And Rendering

CPU VS GPU Rendering (Extensive)


חוּמרָה - המאמרים הפופולריים ביותר

שש דרכים שהד האמזונס הופך את מלווה המטבח המושלם

חוּמרָה Jun 20, 2025

אחד המקומות הטובים ביותר שיש הד אמזון בביתכם הוא במטבח, מכיוון שהרבה אנשים מבלים זמן לא מבוטל באזור ..


כיצד להפעיל את הקן שלך כשתעזוב את העבודה עם Pro אוטומטית

חוּמרָה May 5, 2025

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


כיצד ליצור אזורי פעילות להתראות התנועה של Nest Cam שלך

חוּמרָה Feb 16, 2025

תוכן ללא הכנסה אם אתה רק רוצה שקטע קטן משדה הראייה של Nest Cam שלך יהיה כפוף להתראות תנועה, אתה יוצר "אז�..


כיצד להגדיר את MyQ לפתיחת דלת המוסך מהסמארטפון שלך

חוּמרָה Jan 13, 2025

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


מהי אפליקציית הטלוויזיה של אפל, ועליכם להשתמש בה?

חוּמרָה Jan 4, 2025

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


כיצד להאיץ את כונן המצב המוצק על ידי יישור מחדש של מחיצותיו

חוּמרָה Sep 19, 2025

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


כיצד לגרום למסך השעון של אפל להישאר ארוך יותר

חוּמרָה Nov 30, 2024

תוכן ללא הכנסה לוח השעון בשעון ה- Apple שלך ​​מופיע כאשר אתה מרים את פרק כף היד ומסתתר שוב כשאתה מורי�..


כיצד ליצור ולהפעיל את פודקאסט האודיו שלך

חוּמרָה Jan 10, 2025

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


קטגוריות