Kā CPU un GPU mijiedarbojas ar datoru grafiku?
Jūsu datora centrālā procesora bloks (CPU) un grafikas apstrādes bloks (GPU) darbojas katru reizi, kad izmantojat datoru, lai sniegtu jums skaidru un atsaucīgu vizuālo saskarni. Lasiet tālāk, lai labāk saprastu, kā viņi strādā kopā.
Fotoattēls sskennel.
Šodienas jautājumu un atbilžu sesija mums sniedz pieklājību no SuperUser-Stack Exchange apakšnodaļas, kas ir kopienu disku Q & A tīmekļa vietņu grupa.
Jautājums
SuperUser lasītājs Sathya uzdeva jautājumu:
Šeit jūs varat apskatīt neliela C ++ programmas ekrānu ar nosaukumu Triangle.exe ar rotējošu trijstūri, pamatojoties uz OpenGL API.
Jāatzīst, ka tas ir ļoti svarīgs piemērs, bet es domāju, ka tas ir piemērojams citām grafisko karšu operācijām.
Es biju tikai ziņkārīgs un vēlējos uzzināt visu procesu, sākot ar dubultklikšķi uz Triangle.exe saskaņā ar Windows XP, līdz es redzu trīsstūri, kas rotē monitorā. Kas notiek, kā CPU (kas vispirms apstrādā .exe) un GPU (kas beidzot izvadīs trijstūri uz ekrāna)?
Es domāju, ka šī rotējošā trijstūra parādīšana galvenokārt ir šāda aparatūra / programmatūra, cita starpā:
Aparatūra
- HDD
- Sistēmas atmiņa (RAM)
- Procesors
- Video atmiņa
- GPU
- LCD displejs
Programmatūra
- Operētājsistēma
- DirectX / OpenGL API
- Nvidia Driver
Vai kāds var izskaidrot procesu, varbūt ar kādu diagrammu, kas ilustrē?
Tam nevajadzētu būt sarežģītam paskaidrojumam, kas aptver katru atsevišķu soli (uzminēt, kas būtu plašāks par darbības jomu), bet paskaidrojums starpniekam IT var sekot.
Es esmu diezgan pārliecināts, ka daudzi cilvēki, kas pat sevi sauks par IT speciālistiem, nevarētu pareizi aprakstīt šo procesu.
Atbilde
Lai gan vairāki kopienas locekļi atbildēja uz šo jautājumu, Oliver Salzburg devās uz papildu jūdzi un atbildēja ne tikai ar detalizētu atbildi, bet arī ar izcilu grafiku.
JasonC attēls, pieejams šeit.
Viņš raksta:
Es nolēmu mazliet rakstīt par programmēšanas aspektu un to, kā komponenti runā viens ar otru. Varbūt tas būs nedaudz apgaismots noteiktās jomās.
Prezentācija
Kas nepieciešams, lai pat attēlotu jūsu ekrānā parādīto vienīgo attēlu?
Ir daudz veidu, kā uz ekrāna izdarīt trijstūri. Vienkāršības labad pieņemsim, ka netika izmantoti virsotnes buferi. (A) virsotnes buferisir atmiņas zona, kurā glabājat koordinātas.) Pieņemsim, ka programma vienkārši pastāstīja grafikas apstrādes cauruļvadam par katru virsotni (virsotne ir tikai koordinātes kosmosā) pēc kārtas.
Bet, pirms mēs varam kaut ko izdarīt, mums vispirms ir jābrauc ar sastatnēm. Redzēsim kāpēc vēlāk:
// Notīrīt ekrānu un dziļuma buferu glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Reset Current Modelview Matrix glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Zīmēšana, izmantojot trīsstūri glBegin (GL_TRIANGLES); // Red glColor3f (1.0f, 0.0f, 0.0f); // Trīsstūra tops (priekšējais) glVertex3f (0.0f, 1.0f, 0.0f); // Zaļā glColor3f (0.0f, 1.0f, 0.0f); // Kreisais trijstūris (priekšējais) glVertex3f (-1.0f, -1.0f, 1.0f); // Blue glColor3f (0.0f, 0.0f, 1.0f); // Trīsstūra tiesības (priekšpuse) glVertex3f (1.0f, -1.0f, 1.0f); // Gatavs zīmēšanas attēls ();
Tātad, ko tas darīja?
Rakstot programmu, kas vēlas izmantot grafikas karti, parasti vadītājam izvēlaties kādu interfeisu. Dažas labi zināmas saskarnes ar vadītāju ir:
- OpenGL
- Direct3D
- CUDA
Šajā piemērā mēs pieliksim OpenGL. Tagad, jūsu saskarni ar vadītāju tas, kas dod jums visus rīkus, kas nepieciešami, lai izveidotu programmu runāt uz grafikas karti (vai vadītāju, kas tad sarunas uz karti).
Šī saskarne noteikti dos jums zināmu rīkus. Šie rīki veido API formātu, ko varat zvanīt no savas programmas.
Šī API ir tā, ko mēs redzam iepriekš minētajā piemērā. Apskatīsim tuvāk.
Sastatnes
Pirms jūs patiešām varat veikt kādu faktisku zīmējumu, jums būs jāveic a uzstādīt. Jums ir jādefinē jūsu skata logs (apgabals, kas faktiski tiks sniegts), jūsu perspektīva ( kameru savā pasaulē), ko jūs izmantosiet pretēji (lai izlīdzinātu jūsu trijstūra malas)…
Bet mēs to neuzskatīsim. Mēs vienkārši paskatīsimies uz lietām, kas jums būs jādara katru kadru. Tāpat kā:
Ekrāna dzēšana
Grafikas cauruļvads neparedzēs ekrānu katram rāmim. Jums tas ir jāpasaka. Kāpēc? Tāpēc:
Ja ekrāns netiks dzēsts, jūs vienkārši izdarīt vairāk katru rāmi. Tāpēc mēs aicinām glClear
ArGL_COLOR_BUFFER_BIT
iestatīts. Otrais bits (GL_DEPTH_BUFFER_BIT
) stāsta OpenGL, lai notīrītu dziļumsbuferšķīdumu. Šis buferis tiek izmantots, lai noteiktu, kuri pikseļi atrodas citos pikseļos.
Transformācija
Attēla avots
Transformācija ir tā daļa, kurā mēs izmantojam visas ievades koordinātas (mūsu trijstūra virsotnes) un pielietojam mūsu ModelView matricu. Tā ir šī matrica skaidro kā mūsu modeli (virsotnes) tiek pagrieztas, mērogotas un tulkotas (pārvietotas).
Tālāk mēs izmantojam mūsu projekcijas matricu. Tas pārvieto visas koordinātas, lai tās pareizi saskartos ar mūsu kameru.
Tagad mēs vēlreiz pārveidojam ar mūsu Viewport matricu. Mēs to darām, lai mērogotu mūsu modeli mūsu monitora lielumam. Tagad mums ir virkne virsotņu, kas ir gatavi sniegt!
Vēlāk mēs atgriezīsimies pie transformācijas.
Zīmējums
Lai zīmētu trīsstūri, mēs varam vienkārši pateikt OpenGL, lai sāktu jaunu trijstūru saraksts zvanot glBegin
Ar GL_TRIANGLES
nemainīgs.
Ir arī citas veidlapas, kuras varat izdarīt. Tāpat kā trijstūra sloksne vai trijstūra ventilators. Tie galvenokārt ir optimizācija, jo tie prasa mazāku saziņu starp CPU un GPU, lai izdarītu tādu pašu trīsstūri.
Pēc tam mēs varam piedāvāt sarakstu ar 3 virsotnēm, kas veido katru trijstūri. Katrs trijstūris izmanto 3 koordinātas (kā mēs atrodamies 3D telpā). Turklāt es arī sniedzu a krāsa katram virsotnei, zvanotglColor3f
iepriekš zvanot glVertex3f
.
Starp 3 virsotnēm (trīsstūri 3 stūri) aprēķina OpenGLautomātiski. Tā interpolē krāsu visā daudzstūra sejā.
Mijiedarbība
Tagad, noklikšķinot uz loga. Lietojumprogrammai ir jāaptver tikai loga ziņojums, kas norāda klikšķi. Tad jūs varat palaist jebkuru darbību savā programmā.
Tas kļūst daudz grūtāk, ja vēlaties sākt mijiedarboties ar savu 3D skatījumu.
Vispirms jums ir skaidri jāzina, kurā pikseļa brīdī lietotājs noklikšķināja uz loga. Tad, ņemot savu perspektīvuņemot vērā, jūs varat aprēķināt staru virzienu no peles klikšķa punkta uz savu ainu. Pēc tam varat aprēķināt, vai jūsu ainā ir kāds objekts krustojas ar šo staru. Tagad jūs zināt, vai lietotājs noklikšķinājis uz objekta.
Tātad, kā jūs to pagriežat?
Transformācija
Es zinu divu veidu pārveidojumus, ko parasti izmanto:
- Matricas transformācija
- Kaulu transformācija
Atšķirība ir tā kauli ietekmēt vienu virsotnes. Matricas vienmēr ietekmē visus zīmētos virsotnes tādā pašā veidā. Apskatīsim piemēru.
Piemērs
Agrāk mēs ielādējām mūsu identitātes matrica pirms trīsstūra zīmēšanas. Identitātes matrica ir tāda, kas vienkārši nodrošina nav transformācijas pavisam. Tātad, neatkarīgi no tā, ko es izdarīšu, to skar tikai perspektīva. Tātad trīsstūris vispār netiks pagriezts.
Ja es gribu to pagriezt tagad, es varētu vai nu izdarīt matemātiku (CPU), bet vienkārši zvanīt glVertex3f
arciti koordinātas (kas tiek pagrieztas). Vai es varētu ļaut GPU veikt visu darbu, zvanot glRotatef
pirms zīmēšanas:
// Pagriezt trijstūri uz Y ass glRotatef (summa, 0.0f, 1.0f, 0.0f);
summu
protams, ir tikai fiksēta vērtība. Ja Tu gribi animēt, jums būs jāseko summu
un palieliniet to katru kadru.
Tātad, pagaidiet, kas notika ar visu matricas sarunu agrāk?
Šajā vienkāršajā piemērā mums nav jārūpējas par matricām. Mēs vienkārši zvanām glRotatef
un tas rūpējas par visu par mums.
glRotate
rada rotācijuleņķis
grādi ap vektoru x y z. Pašreizējo matricu (seeglMatrixMode) reizina ar rotācijas matricu ar produktu, kas aizstāj pašreizējo matricu, jo ifglMultMatrix tika izsaukts ar šādu matricu kā argumentu: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
Nu, paldies par to!
Secinājums
Kas kļūst skaidrs, ir daudz runāt uz OpenGL. Bet tas nenozīmē mums neko. Kur ir komunikācija?
Vienīgais, ko OpenGL mums saka šajā piemērā kad tas ir izdarīts. Katrai darbībai būs vajadzīgs zināms laiks. Dažas operācijas ir neticami garas, citas ir neticami ātras.
Virsotnes nosūtīšana GPU būs tik ātri, es pat nezinu, kā to izteikt. Tūkstošiem virsotņu nosūtīšana no CPU uz GPU, katrs rāmis, visticamāk, nav vispār.
Ekrāna dzēšana var būt milisekundes vai sliktāks (paturiet prātā, ka parasti katram kadram parasti ir tikai aptuveni 16 milisekundes), atkarībā no tā, cik liels ir jūsu skatīšanās logs. Lai to izdzēstu, OpenGL ir jāpieliek katrs atsevišķais pikseļa krāsa, kuru vēlaties dzēst, kas varētu būt miljoniem pikseļu.
Izņemot to, ka mēs varam diezgan daudz vaicāt tikai OpenGL par mūsu grafikas adaptera iespējām (maksimālā izšķirtspēja, maksimālā pretestība, maksimālais krāsu dziļums,…).
Bet mēs varam arī aizpildīt tekstūru ar pikseļiem, kuriem katram ir īpaša krāsa. Līdz ar to katram pikseļiem ir vērtība, un tekstūra ir milzīgs “fails”, kas ir aizpildīts ar datiem. To var ielādēt grafikas kartē (izveidojot tekstūras buferi), tad ielādēt ēnotāju, pateikt, ka ēnotājs izmanto mūsu tekstūru kā ievades metodi un palaidīs dažus ārkārtīgi smagus aprēķinus mūsu failā.
Tad mēs varam “padarīt” mūsu aprēķina rezultātu (jaunu krāsu veidā) jaunā tekstūrā.
Tādā veidā jūs varat padarīt GPU darbu citā veidā. Es pieņemu, ka CUDA darbojas līdzīgi šim aspektam, bet man nekad nav bijusi iespēja strādāt ar to.
Mēs tiešām tikai nedaudz aizskāra visu tematu. 3D grafikas programmēšana ir zvērs.
Attēla avots
Vai kaut kas jāpievieno paskaidrojumam? Skaņas izslēgšana komentāros. Vai vēlaties lasīt vairāk atbildes no citiem tehnoloģiju gudriem Stack Exchange lietotājiem? Apskatiet pilnu diskusiju pavedienu šeit.