2010-01-17

Performanta in sistemele multi-cpu si multi-core

Performanta in sistemele multi-cpu

  Articol pentru programatori in special. O prezentare foarte interesanta (engleza) se afla la final. O sa extrag cateva idei care mi se par interesante despre optimizare performanta din perspectiva hardware. Informatiile sunt relevante pentru achizitionarea procesoarelor si pentru "tuning" aplicatii software.


  Ce limiteaza viteza de procesare

  •   Procesoarele au atins o limita tehnologica pe la viteza de 3Ghz. Intr-o cuanta de timp atat de mica (1s/3.000.000.000), lumina (si orice alt semnal) poate parcurge doar aproximativ 10cm, ordinul de marime al unui procesor. Procesorul nu poate functiona mai repede pentru ca atat ii ia semnalului electric sa faca o tura prin procesor.
  • Procesorul reordoneaza executia unor instructiuni care nu depind unele de altele, pentru a putea executa mai multe operatii intr-o singura cuanta de timp, in paralel. De multe ori insa operatia urmatoare depinde de rezultatul celei precedente, deci nu se poate lansa a doua operatie pana nu se termina prima.
  •  Pentru a creste performanta, s-a inceput crearea procesoarelor multi-core, care incearca sa imparta procesarea pe mai multe unitati procesor. Din cauza interdependenti intre operatii, un program rulat pe 2 procesoare obtine de obicei mult sub dublul performante.
  • Un program care are doar un fir de executie (thread) obtine pe doua procesoare sub 10% in plus fata de a rula pe un singur procesor. Pe de alta parte se pot rula doua programe in paralel la aceeasi viteza cu a le rula pe fiecare singure pe un procesor. Este vorba de programe care consuma mult CPU fiecare, nu programe care stau deschise fara sa faca nimic.
  • Memoria RAM functioneaza cam de 100 ori mai lent decat procesorul, la fel cum Hard-Discul este mult mai lent fata de RAM. Pentru ca procesorul sa poata executa instructiuni la viteza maxima, exista cache-ul L1 care functioneaza aproximativ la viteza procesorului.
  • Cache-ul este o fereastra spre memorie. El incarca zona de memorie care este in executie, iar cat timp executia nu iese din acea zona procesorul poate functiona la viteza maxima.
  • Imediat ce executia iese din fereastra de cache, procesorul asteapta echivalentul a peste 100 de instructiuni sa se incarce o noua bucata din memorie in cache. De aceea un cache L1 mai mare inseamna o viteza mai mare de executie. Cache-ul L1 este foarte scump, deci mic. Unele procesoare au si cache L2 (de 10 ori mai lent si de 10 ori mai mare/ieftin).
  •  Exista si cache L3 care este doar de aproximativ 2 ori mai rapid decat memoria RAM, dar care ajuta sistemele multiprocesor sa nu congestioneze accesul la memoria RAM.
  •  Viteza de executie a unui program nu mai depinde atat de tare de frecventa procesorului, cat de numarul de accesari ale memoriei pe care nu le gaseste in cache. Algoritmi complexi incearca sa pre-incarce in cache memoria necesara in viitorul apropiat, totusi in multe cazuri nu reuseste.
  • Chiar si un 5% de "cache miss" (accesari ale memoriei in afara zonei cache) scade performanta drastic. In loc ca 100 operatii sa dureze 100 cuante timp, vor dura 95+5*100, deci aproape de 6 ori mai mult decat ar dura executate 100% in cache. S-ar putea ca un cache L1 mai mare sa ajute mai mult decat arata benchmark-urile, intrucat programele  benchmark sunt relativ mici, putand sa incapa complet in cache.
  • Viteza cu care ruleaza un program tine foarte mult de felul in care sunt aranjate instructiunile in memorie. Compilatoarele si masinile virtuale incearca sa ajute la aceasta operatie. Salturile in structuri mari de date si "indirectarile" produc totusi foarte multe salturi in afara zonei de memorie incarcate in cache, deci scad performanta.
  • Programarea orientata pe obiecte (C++) tinde sa genereze multe obiecte distribuite in zone de memorie ne-alaturate, deci un cod care iese mai des din cache. Programarea C foloseste in general functii mai mari, indirectari mai putine, zone de date mai compact distribuite, deci are sanse sa genereze un cod care foloseste cache-ul mai eficient.
  • Atunci cand procesorul asteapta dupa memoria RAM, procesorul va arata incarcat 100%, desi el de fapt ... sta degeaba. Este aproape inposibil de detectat impactul iesirilor din cache asupra vitezei, altfel decat prin teste cu diferite procesoare.


   Probleme de concurenta in sistemele multiprocesor

  •    Sistemele multiprocesor au cate un cache langa fiecare procesor. Sincronizarea cu memoria este un proces complex, care de multe ori blocheaza un procesor in asteptarea rezultatului altui procesor. Cache-urile "discuta" intre ele despre locatiile de memorie folosite in paralel
  • Din considerente de performanta, citirile din RAM nu se fac in aceeasi ordine cu scrierile, cel putin pe arhitectura x86/PC. Ce se garanteaza este doar ca fiecare procesor va vedea actualizat ce a scris el. Scrierile altui procesor pot ajunge in alta ordine via memorie.
  • Sa luam doua threaduri care pornesc ambele cu variabilele comune flag=0 si adresa=0. Primul thread seteaza adresa=123 si apoi semnaleaza asta punand flag=1. Este posibil ca un alt thread, pe alt procesor, sa vada flag=1 dar adresa=0 (nemodificata). In foarte scurt timp, si al doilea thread va putea vedea ca flag=1 si adresa=123. Totusi, daca al doilea thread verifica flag-ul exact dupa modificare, ajunge sa foloseasca adresa=0 (ne-initializata).
  • Pentru sincronizarea corecta a accesului la date folosite in comun de threaduri trebuie folosite lock-uri/mutexi, care elimina problema de reordonare pe multi-core. Primitivele de lock evalueaza si modifica atomic variabilele mutex, astfel ca un alt procesor nu poate citi in mijlocul operatiei. Din pacate aceasta sincronizare va bloca pentru scurt timp activitatea tuturor procesoarelor, si va inactiva informatia din cache-ul celorlalte procesoare, ceea ce duce la pierderi in performanta.

  Concluzie: devine tot mai importanta intelegerea arhitecturii hardware pentru crearea unui soft performant ca viteza. Programele viitorului trebuie sa poata fi executate pe fire de executie paralele si cu interdependente cat mai mici, pentru a putea scala pe tot mai multe cores. Frecventa procesoarelor nu va mai creste mult, doar vom avea din ce in ce mai multe procesoare impachetate intr-un cip.

A Crash Course in Modern Hardware:

http://www.infoq.com/presentations/click-crash-course-modern-hardware

5 comentarii:

x spunea...

Limita de 3GHz este probabil pt procesoarele actuale.
Vechiul Pentium 4 a fost overclockat până peste 5 GHz
Uite aici dovada.
Nu se spune cât de stabil era la frecvenţa aceea, dar mai sunt filmuleţe pe youtube cu Procesorul la 4 GHz şi care e stabil.

Mihvoi spunea...

Interesant, nu stiam. Oricum este de retinut ca de acum incolo lesa se strange, cu cat cresti frecventa, cu atat poti sa faci mai putine in acel ciclu de tact, pentru ca lungimea traseului pe care o poate parcurge semnalul se micsoreaza.

y spunea...

eu tin cpu la 3.6Ghz(3Ghz default)si nu s-a micsorat nimic inafara timpului de executie,din contra :).Nu e cazul sa folosim logica inversa,cred ca e pur si simplu vorba de cresterea vitezei semnalului pe aceeasi lungime de circuit(lungimea este constanta);evident ca exista o limita tehnologica(fenomenul de electro-migratie).Stima

Anonim spunea...

nici pt procesoarele actuale nu exista aceasta limita(google-record 6ghz)din cauza voltajelor scazute si a materialelor noi.Personal tin cpu meu in 3.6-4Ghz si nu s-a micsorat decat timpul de executie.De ce folosesti logica inversa?(lungimea traseului este intotdeauna constanta-creste doar viteza semnalului pe aceeasi lungime a circuitului).viteza de 3ghz este o viteza "safe" impotriva electromigratiei

Mihvoi spunea...

Eu zic ca se vede cu ochiul liber ca viteza de crestere a frecventei procesoarelor a scazut aproape de zero.
Nu spun ca un overclock nu poate functiona inca. Probabil in aia 10cm nu sunt inca consumati complet de porti logice, si miniaturizarea va mai continua putin pana la efectul amintit poate. Probabil inca limitarea este data de disipatia termica, stabilitatea circuitelor, efectul de capacitate care taie/defazeaza frecventele inalte (ce mai stiu si eu de la fizica).

As fi crezut ca explicatia mea cu timpul de intoarcere a raspunsului din procesor poate fi inexacta, daca nu aparea si in prezentarea in engleza la care dau link in final.

Timpul de efectuare a unei operatii este ca timpul de ping. Oricata latime de banda ai avea, primul bit al paginii web cerute nu poate veni mai repede decat timpul de ping, care nu poate fi mai scurt decat timpul de propagare a luminii pe acel traseu. Restul bitilor pot veni intr-un timp oricat de scurt teoretic, daca ai avea la dispozitie multe linii paralele care sa transmita fiecare cate un bit. Dar mai repede decat viteza luminii nu se intoarce pingul sau primul bit.
Aplicat la procesoare, nu poti incepe urmatoarea operatie depinzand de prima pana nu se intoarce raspunsul la la prima. Probabil se pot gasi tehnici de comunicare cu procesorul similare cu TCP/IP (fereastra de congestie), dar timpul de la venirea unei comenzi pana la primul bit de raspuns va tinde asimptotic la ceva de care nu suntem departe.

Facebook