Placa de bazaUnitatea centrală de procesare (CPU - Central Processing Unit) şi unitatea grafică de procesare (GPU) ale computerului tău interacţionează continuu pentru a-ţi oferi o interfaţă vizuală limpede, clară şi caldă. Dar cum lucrează împreună cele două componente de procesare?

 

 

 

Orice calculator conţine un procesor (numit şi CPU), care este baza oricărui calculator şi un procesor grafic (numit şi GPU = Graphic Processing Unit). Pe cel din urmă îl regăsim cu toţii atunci când, din diverse necesităţi, achiziţionăm o placă video pe care o ataşăm plăcii de bază a calculatorului; placa video, pe lângă memorie, mai are ataşat pe ea şi acel GPU. El este cel care procesează grafica computerizată ce o vedem pe ecran, dar nu poate face totul singur, folosindu-se şi de CPU. Deci CPU şi GPU lucrează împreună la generarea graficii computerizate.

 

Triunghi



Triunghiul este generat de o aplicaţie scrisă în limbajul de programare C++; mica aplicaţie se numeşte Triangle.exe şi este bazată pe OpenGL.

OpenGL (Open Graphics Library), conform definiţiei de pe Wikipedia (en.wikipedia.org/wiki/OpenGL) este un standard care defineşte scrierea de aplicaţii care generează grafică computerizată, deci, ca şi DirectX, e o colecţie de API-uri pentru controlul funcţiilor multimedia. Spre deosebire de DirectX, OpenGL suportă mai multe platforme.

DirectX este asemănător cu OpenGL şi reprezintă, conform definiţiei de pe Wikipedia (ro.wikipedia.org/wiki/DirectX) o colecţie de API-uri pentru controlul funcţiilor multimedia, în special pentru programarea jocurilor, pe platformele Windows.

API-urile (Application Programming Interface) reprezintă denumirea (în limba engleză) a unei interfeţe pentru programarea de aplicaţii. Conform Wikipedia (ro.wikipedia.org/wiki/API), această interfaţă dintre programele ce rulează şi sistemul de operare stabileşte cum acestea pot accesa diferite resurse ale sistemului de operare; mai simplu, API-urile stabilesc modul cum aplicaţiile interacţionează cu sistemul de operare.

Întrebarea

Dar, în cazul de faţă, cazul triunghiului, să vedem ce se întâmplă din momentul în care deschidem aplicaţia Triangle.exe şi până când vedem triunghiul rotindu-se pe monitor. Cum procesează la început CPU executabilul şi, mai departe, cum interacţionează cu GPU pentru a ajunge, în final, să vedem acel triunghi rotindu-se pe ecran?

Pentru a răspunde la întrebare, mai întâi să vedem cerinţele de sistem:

Hardware:
- HDD (hard disk) sau, mai româneşte spus, hardul calculatorului,
- memoria sistemului de tip RAM (RAM = Random Access Memory);
- CPU, numit mai simplu procesor calculatorului sau doar procesor;
- memoria video, care este utilizată de GPU pentru a afişa în final triunghiul;
- monitor.

Software:

- sistemul de operare, fără de care un calculator nu ar putea fi operaţional;
- DirectX/OpenGL;
- drivere pentru placa video; acestea din urmă sunt absolut necesare pentru ca sistemul de operare să recunoască placa video şi să ştie cum să o folosească.

Răspunsul la întrebarea "Cum interacţionează CPU cu GPU pentru a genera grafici computerizate?" nu este neapărat unul complex, dar probabil că sunt mulţi care se consideră pricepuţi în IT şi nu ar putea descrie procesul corect.

Deşi mulţi din membri comunităţii au răspuns la întrebare, să vedem ce ne spune Oliver Salzburg.


Răspunsul

Sunt multe metode de a desena un triunghi pe ecran. Pentru simplitate, să presupunem că nu sunt utilizate vertex buffers (vertex buffer = o zonă din memorie în care sunt stocate coordonatele. Să presupunem că programul este atât de simplu încât spune unităţii de procesare grafică toate vertex-urile deodată (un vertex este doar o coordonată din spaţiu, a triunghiului).


Mai jos avem codul sursă al aplicaţiei Triangle.exe.

// 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();


Când scrii un program care utilizează placa video, trebuie să alegi o interfaţă de comunicare cu driver-ul acesteia; ştim că un driver reprezintă un program necesar pentru ca sistemul de operare să poată recunoaşte placa video şi ca aplicaţiile să o poată utiliza.

Unele dintre cele mai bine cunoscute interfeţe pentru drivere sunt:
- OpenGL;
- Direct3D;
- CUDA (Compute Unified Device Architecture) - este, conform definiţiei de pe Wikipedia (ro.wikipedia.org/wiki/CUDA), o arhitectură de software şi hardware pentru calculul paralel al datelor dezvoltată de către compania americană NVIDIA. CUDA este utilizată atât în seriile de procesoare grafice destinate utilizatorilor obişnuiţi, cât şi în cele profesionale.

Pentru acest exemplu ne vom rezuma la OpenGL. Interfaţa către driverul plăcii video este cea care oferă uneltele care sunt necesare pentru a face ca programul Triangle.exe să comunice cu placa video.

Înainte de a desena ceva este necesar să fie efectuate nişte setări. Astfel, trebuie definit viewport-ul (zona care va fi randată, adică generată grafic), perspectiva (unghiul camerei din lumea virtuală), ce grad de anti-aliasing să fie folosit (anti-aliasing-ul este o metodă care face ca muchiile obiectelor să nu se vadă zimţat, ci să se vadă mai fin).

Pentru a genera corect o imagine, orice imagine, nu doar triunghiul, trebuie curăţat ecranul. Dacă nu este curăţat, noua imagine va apărea, dar suprapusă peste cealaltă. Un astfel de exemplu poate fi văzut mai jos:

 

Ferestre suprapuse


Desenarea triunghiului se poate face accesând o listă de triunghiuri din OpenGL astfel: glBegin cu GL_TRIANGLES constant. Sunt şi alte forme care pot fi desenate. Acestea sunt optimizări primare care necesită un nivel de comunicaţie mai redus dintre CPU şi GPU, când trebuiesc desenate mai multe triunghiuri identice. După acest pas, se trece la introducerea coordonatelor triunghiului; fiecare triunghi utilizează 3 coordonate. În plus, pot fi alese şi culori. Gradul de umbrire de pe cele 3 laturi ale triunghiului este calculat de OpenGL în mod automat.

Interacţiunea


Acum, executând click în fereastra aplicaţiei, aceasta trebuie să preia mesajul care semnalează acel click. Pe urmă se poate rula orice acţiune este dorită în program.

Este însă mai dificil când se doreşte interacţiunea cu scena 3D. Mai întâi, trebuie ştiut clar pe ce pixel din fereastră a dat click utilizatorul. Apoi, ţinând cont de perspectivă, se poate calcula direcţia unei raze din punctul de click de mouse în scenă. Pe urmă, există posibilitatea de a calcula dacă orice obiect din scenă se intersectează cu raza. Acum se poate şti dacă utilizatorul a făcut click pe un obiect.

Dar cum se face triunghiul să se rotească?


Transformarea

Sunt 2 tipuri de transformări care sunt folosite în mod curent:
- transformarea bazată pe matrice (matrix-based transformation);
- transformarea bazată pe matrice os (matrix-bone transformation).

Exemplu:

Dacă este încărcată doar matricea identitate înainte de a desena triunghiul, acesta nu v-a suferi nicio transformare. Orice desenăm este afectat numai de perspectivă iar triunghiul nu se va roti.

Matricea identitate  (identity matrix), conform Wikipedia (en.wikipedia.org/wiki/Identity_matrix) este o matrice care are pe diagonală numai elemente egale cu 1, iar restul elementelor sunt nule (0).

Dar dacă se doreşte rotirea triunghiului acum, se poate face fie cu CPU, apelând comanda glVertex3f împreună cu alte coordonate care sunt rotite.

Sau poate fi lăsată munca în seama GPU apelând comanda glRotate:

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

În acest exemplu simplu nu mai este necesar a avea grija matricelor. Apelând comanda glRotate este realizată rotirea triunghiului.


Concluzia:

Este evident că este mult de vorbit despre OpenGL, dar nu ne-a spus nimic despre comunicarea dintre CPU şi GPU; unde este această comunicare?

Singurul lucru care care ni-l spune OpenGL în acest exemplu este atunci când desenul este gata. Fiecare operaţiune necesită un anumit timp. Unele durează incredibil de mult iar altele sunt foarte rapide. Trimiterea unei comenzi către este atât de rapidă încât nu poate fi simţită ca timp la fel ca şi trimiterea miilor de coduri pentru fiecare cadru al animaţiei. Curăţarea ecranului poate dura în jur de o milisecundă (a mia parte dintr-o secundă) sau mai mult, de obicei cam 16 milisecunde pentru fiecare cadru, depinzând şi de mărimea ferestrei de generare grafică. Pentru a curăţa ecranul, OpenGL trebuie să deseneze fiecare pixel şi pot fi milioane de pixeli. La o rezoluţie a ecranului de 1280x1204 pixeli, numărul total de pixeli este chiar produsul înmulţirii rezoluţiei deci 1310720 pixeli. Mai mult, trebuie să se ţină cont şi de capacităţile maxime ale plăcii video utilizate (rezoluţia maximă, cate culori pot fi alocate fiecărui pixel, gradul maxim de finisare al muchiilor obiectelor, etc.).


Tradus după how-do-the-cpu-and-gpu-interact-to-render-computer-graphics de Marcoşanu Dragoş