Hogyan működik a CPU és a GPU a számítógépes grafika megjelenítéséhez?

Tartalomjegyzék:

Hogyan működik a CPU és a GPU a számítógépes grafika megjelenítéséhez?
Hogyan működik a CPU és a GPU a számítógépes grafika megjelenítéséhez?

Videó: Hogyan működik a CPU és a GPU a számítógépes grafika megjelenítéséhez?

Videó: Hogyan működik a CPU és a GPU a számítógépes grafika megjelenítéséhez?
Videó: How To Disable Help Tips Windows 8.1 - YouTube 2024, Április
Anonim
A számítógép központi feldolgozóegysége (CPU) és a grafikus feldolgozó egység (GPU) minden pillanatban kölcsönhatásba lépnek a számítógéppel, hogy éles és érzékeny vizuális felületet biztosítson Önnek. Olvassa el, hogy jobban megértse, hogyan működnek együtt.
A számítógép központi feldolgozóegysége (CPU) és a grafikus feldolgozó egység (GPU) minden pillanatban kölcsönhatásba lépnek a számítógéppel, hogy éles és érzékeny vizuális felületet biztosítson Önnek. Olvassa el, hogy jobban megértse, hogyan működnek együtt.

A képet készítette sskennel.

A mai Kérdések és válaszok munkamenetét a SuperUser - a Stack Exchange, a Q & A weboldalak közösségi meghajtó csoportosulásának részlegével - köszönheti.

A kérdés

SuperUser olvasó Sathya felvetette a kérdést:

Itt láthat egy screenshotot egy kis C ++ programról, a Triangle.exe-nek, az OpenGL API-n alapuló forgó háromszög segítségével.

Kétségtelenül egy nagyon alapos példa, de úgy gondolom, ez más grafikai kártyák műveleteire is alkalmazható.
Kétségtelenül egy nagyon alapos példa, de úgy gondolom, ez más grafikai kártyák műveleteire is alkalmazható.

Csak kíváncsi voltam, és tudtam, hogy az egész folyamat dupla kattintással a Triangle.exe alatt fut a Windows XP alatt, amíg meg nem látom a monitoron forgó háromszöget. Mi történik, hogyan működnek együtt a CPU (amelyik először kezeli az.exe-t) és a GPU-t (amely végül a képernyőn megjelenő háromszöget adja ki)?

Úgy gondolom, hogy részt vesz a forgó háromszög megjelenítésében, elsősorban a következő hardver / szoftver:

Hardver

  • HDD
  • Rendszer memória (RAM)
  • processzor
  • Videomemória
  • GPU
  • LCD kijelzö

Szoftver

  • Operációs rendszer
  • DirectX / OpenGL API
  • Nvidia illesztőprogram

Meg tudja magyarázni a folyamatot, talán egyfajta folyamatábrán illusztrálva?

Ez nem lehet egy összetett magyarázat, amely minden egyes lépésre kiterjed (feltételezzük, hogy túlmutatnánk a határokon), de egy magyarázatot, amelyet egy közbenső IT fickó követhet.

Biztos vagyok benne, hogy sok ember, aki még magát is nevezi magát, az informatikai szakemberek nem tudták pontosan leírni ezt a folyamatot.

A válasz

Image
Image

Bár több közösség tagjai válaszoltak a kérdésre, Oliver Salzburg elment az extra mérföldre és válaszolt nemcsak részletes választ, de kiváló kísérő grafikát.

Image by JasonC, háttérképként elérhető.

Ír:

Úgy döntöttem, hogy egy kicsit írok egy kicsit a programozási szempontról és arról, hogy az összetevők hogyan beszélnek egymással. Talán bizonyos területeken némi fényt hoz.

A prezentáció

Mit kell tennie ahhoz, hogy a képen feltüntetett egyetlen képet, amit a kérdésedre írtak?

Számos módon lehet háromszöget rajzolni a képernyőn. Az egyszerűség kedvéért tegyük fel, hogy nem használtunk vertex puffereket. (A vertex pufferegy olyan memóriaterület, ahol a koordinátákat tároljuk.) Tegyük fel, hogy a program egyszerűen megmondta a grafikus feldolgozó vezetéket minden egyes csúcsról (a csúcs csak egy koordinátája a térben) egy sorban.

De, mielőtt bármit rajzolnánk, először meg kell állítanunk néhány állványt. Meglátjuk miért majd később:

// Clear The Screen And The Depth Buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Reset The Current Modelview Matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Drawing Using Triangles glBegin(GL_TRIANGLES); // Red glColor3f(1.0f,0.0f,0.0f); // Top Of Triangle (Front) glVertex3f( 0.0f, 1.0f, 0.0f); // Green glColor3f(0.0f,1.0f,0.0f); // Left Of Triangle (Front) glVertex3f(-1.0f,-1.0f, 1.0f); // Blue glColor3f(0.0f,0.0f,1.0f); // Right Of Triangle (Front) glVertex3f( 1.0f,-1.0f, 1.0f); // Done Drawing glEnd();

Tehát mit csinált?

Amikor olyan programot ír be, amely a grafikus kártyát kívánja használni, akkor rendszerint egyfajta interfészt választasz a sofőrhöz. Néhány jól ismert interfész a vezetőhöz:

  • OpenGL
  • Direct3D
  • CUDA

Ebben a példában ragaszkodunk az OpenGL-hez. Most, a te interfész a vezetőhöz ez adja az összes eszközt, amire szüksége van a program elkészítéséhez beszélgetés a grafikus kártyához (vagy a sofőrhöz) beszél a kártyára).

Ez az interfész biztos, hogy bizonyos szerszámok. Ezek az eszközök olyan API formátumúak, amelyek a programból hívhatók.

Ez az API az, amit a fenti példában használunk. Nézzünk közelebb.

Az állványzat

Mielőtt tényleges rajzot készítene, végre kell hajtania a beállít. Meg kell határoznia a nézetportot (a ténylegesen megjelenített területet), a perspektíváját (a kamera a világodba), milyen anti-aliasing fogsz használni (hogy simítsa ki a széleit a háromszög) …

De nem fogunk semmit nézni. Csak megnézzük a dolgokat, amiket meg kell tennie minden keretben. Mint:

A képernyő törlése

A grafikus csővezeték nem fogja törölni a képernyőt minden keretben. Meg kell mondania. Miért? Ez az oka:

Image
Image

Ha nem törli a képernyőt, akkor egyszerűen húzni minden keretet. Ezért hívjuk

glClear

a … val

GL_COLOR_BUFFER_BIT

készlet. A másik bit (

GL_DEPTH_BUFFER_BIT

) megmondja az OpenGL-nek, hogy törölje mélységpuffer. Ezt a puffert használjuk annak meghatározására, hogy mely képpontok vannak (vagy mögötte) más képpontok.

átalakítás

 Képforrás
Képforrás

Az átalakítás az a része, ahol minden bemeneti koordinátát (a háromszög csúcsai) veszünk és alkalmazzuk a ModelView mátrixunkat. Ez a mátrix magyarázza hogyan modell (a csúcsok) elforgatásra, méretezésre és lefordításra (mozgatásra) kerül sor.

Ezután alkalmazzuk a vetítési mátrixunkat. Ez mozgatja az összes koordinátát úgy, hogy a fényképezőgéppel szembenézzen.

Most ismét átalakítjuk a Viewport mátrixunkat. Ezt azért teszik, hogy mérlegeljük modell a monitor méretéhez. Most van egy sor csúcsa, amely készen áll a rendezésre!

Visszatérünk az átalakuláshoz egy kicsit később.

Rajz

Háromszög rajzolásához egyszerűen megmondhatjuk az OpenGL-nek, hogy újat kezdjen a háromszögek listája hívással

glBegin

a … val

GL_TRIANGLES

állandó. Vannak más formák is, amelyeket rajzolhat. Mint egy háromszög szalag vagy háromszög ventilátor.Ezek elsősorban optimalizáltak, mivel a CPU és a GPU között kevesebb kommunikációra van szükség, hogy azonos mennyiségű háromszöget húzzanak meg.

Ezután megadhatunk három csúcskészletet, amelyeknek minden háromszöget ki kell alakítaniuk. Minden háromszög három koordinátát használ (mint a 3D térben). Továbbá, én is a szín minden csúcsra hívással

glColor3f

előtt hívás

glVertex3f

A három csúcs közötti árnyalatot (a háromszög három sarkát) az OpenGL számítja ki automatikusan. Az interpolálja a színt a poligon teljes felületén.

Interakció

Most, amikor rákattint az ablakra. Az alkalmazásnak csak a kattintást jelző ablak üzenetet kell tartalmaznia. Ezután a kívánt programban végrehajthat bármilyen műveletet.

Ez megkapja a sok még nehezebbé válik, ha elkezdi a 3D jelenettel való interakciót.

Először tisztában kell lennie azzal, hogy a felhasználó melyik képpontra kattintott az ablakban. Akkor vegye be távlatifigyelembe véve, akkor kiszámíthatja a sugár irányát, az egérkattintás pontjáról a jelenetre. Ezután kiszámíthatja, hogy a jelenet bármely objektuma metsző azzal a sugárral. Most már tudod, hogy a felhasználó rákattintott-e egy objektumra.

Szóval, hogyan forgatja el?

átalakítás

Tisztában vagyok az átalakítások két típusával, amelyeket általánosan alkalmaznak:

  • Mátrix-alapú transzformáció
  • Csontalapú transzformáció

A különbség az, hogy csontok befolyásolja az egyszemélyes csúcsok. A mátrixok mindig ugyanúgy érintik az összes csúcsot. Nézzünk egy példát.

Példa

Korábban betöltöttük a miét azonosító mátrix mielőtt háromszögünket rajzoljuk. Az azonosító mátrix az, amely egyszerűen biztosítja nincs átalakulás egyáltalán. Tehát, amit rajzolok, csak az én perspektívám érinti. Tehát a háromszög egyáltalán nem forog.

Ha most forgatni akarom, magam is megtehetném a matematikát (a CPU-n), és egyszerűen hívhatnám

glVertex3f

val velmás koordináta (forgatva). Vagy hagyhatnám, hogy a GPU végezze el az összes munkát, felhívva

glRotatef

rajzolás előtt:

// Rotate The Triangle On The Y axis glRotatef(amount,0.0f,1.0f,0.0f);

amount

természetesen csak egy fix érték. Ha akarod élő, nyomon kell követnie

amount

és növelje minden keretet.

Szóval, várj, mi történt korábban az összes mátrix beszélgetéssel?

Ebben az egyszerű példában nincs szükségünk a mátrixokra. Egyszerűen hívjuk

glRotatef

és gondoskodik róla mindenről.

glRotate

forgat

angle

fokok az x y z vektor köré. Az aktuális mátrixot (seeglMatrixMode) megszorozzuk egy forgatómátrixmal az aktuális mátrixot felváltó termékkel, mintha azglMultMatrix-et az alábbi mátrixmal hívnánk az argumentumaként:

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 0 x z z 1 - c - y cz cz 1 - c + xsz 2 ⁡ 1 - c + c 0 0 0 0 1

Nos, köszönöm!

Következtetés

Ami nyilvánvalóvá válik, sok vita van nak nek OpenGL. De nem mondja el minket bármi. Hol van a kommunikáció?

Az egyetlen dolog, amit az OpenGL mond nekünk ebben a példában amikor elkészült. Minden művelet egy bizonyos időt vesz igénybe. Néhány művelet hihetetlenül hosszú, mások hihetetlenül gyorsak.

Egy csúcs küldése hogy a GPU olyan gyors lesz, nem is tudom, hogyan kell kifejezni. Ha több ezer vertikát küldenek a CPU-ból a GPU-ba, minden egyes kocka, valószínűleg egyáltalán nincs probléma.

A képernyő törlése akár egy milliszekundum vagy még rosszabb is lehet (szem előtt tartva, általában csak 16 milliszekundumnyi időtartam van, hogy rajzoljon minden egyes kockát) attól függően, hogy milyen nagy a nézetablaka. A törléshez az OpenGL-nek minden egyes képpontot meg kell rajzolnia a színt, amelyet törölni akar, ami millió pixel lehet.

Emellett csak annyit kérdezhetünk az OpenGL-től, hogy grafikus adapterünk (max felbontás, max anti-aliasing, max színmélység, …) képes.

De egy olyan textúrát is feltölthetünk, amelynek képpontjai mindegyiküknek egyedi színe van. Így minden pixelben van egy érték, és a textúra egy óriási "adat". Ezt beilleszthetjük a grafikus kártyába (textúra puffer készítésével), töltsünk be egy árnyékolót, mondjuk meg, hogy a shader textúráját bemenetként használja, és nagyon nagy számításokat futtat a "fájlunkon".

Ezután "kiszámítjuk" a számításunk eredményét (új színek formájában) egy új textúrába.

Így teheti meg a GPU más módon is. Feltételezem, hogy a CUDA hasonlít az adott szempontra, de soha nem volt alkalma dolgozni vele.

Igazából csak kissé megérintettük az egész témát. A 3D grafikus programozás egy fenevad öröme.

Image
Image

Kép forrása

Van valami a magyarázathoz? Hangzik ki a megjegyzésekben. Szeretne többet válaszolni a többi technikus-tudós Stack Exchange felhasználóiról? Nézze meg a teljes vitafonalat itt.

Ajánlott: