Ce este o blocare a memoriei?

Din punct de vedere istoric, toate programele de calculator au fost scrise într-un mod complet secvenţial. Acest lucru este simplu de citit, scris și înțeles. Este, de asemenea, simplu de executat pentru un computer și necesită hardware relativ simplu. Cu această paradigmă de proiectare, singurele două moduri de a crește performanța sistemului sunt să scrieți cod mai eficient și să creșteți viteza procesorului. Creșterea eficienței codului poate fi posibilă, dar este, în general, un proces complex, cu rezultate adesea limitate.

Timp de decenii, performanța ar putea fi scăzută prin așteptarea unor procesoare noi, mai eficiente. După cum este descris de legea lui Moore, CPU-urile se dublează aproximativ la fiecare doi până la trei ani. Din păcate, majoritatea acestor câștiguri de performanță au venit din utilizarea nodurilor de producție din ce în ce mai mici. Tehnologia modernă s-a luptat să scadă dimensiunea nodului la ritmul istoric, datorită dificultăților materiale de lucru la scara nanometrilor.

Pentru a ocoli acest lucru, arhitecții moderni de procesoare au optat pentru a adăuga mai multe nuclee de procesor la procesoare. Fiecare nucleu de procesor poate acționa independent asupra unei sarcini diferite. Deși nu pot combina aceeași problemă, pot lucra la două probleme simultan. Această schimbare arhitecturală fundamentală oferă o mulțime de performanțe suplimentare, dar nu beneficiază în mod direct procesele individuale, deși reduce disputele pentru timpul procesorului.

Pentru a profita de procesoarele cu mai multe nuclee, codul trebuie scris într-un mod multi-thread. Fiecare fir de execuție poate fi rulat concomitent, mărind avantajul de performanță cu numărul de fire disponibile și nuclee CPU. Făcând acest lucru, totuși, se confruntă cu o nouă provocare, „condiția de cursă”.

Notă: Unele sarcini nu pot fi multi-threaded, în timp ce altele pot fi masiv multi-thread. Posibilele beneficii ale performanței se bazează pe munca depusă.

Condiții de cursă

Software-ul cu mai multe fire poate profita de mai multe nuclee. Pericolele pândesc în acele ape, gata să-l prindă în capcană pe programatorul neexperimentat. O condiție de cursă poate apărea atunci când două fire diferite interacționează cu același bit de memorie.

Un exemplu simplu ar putea fi două fire care încearcă să verifice și să incrementeze o variabilă simultan. Să presupunem că a=0 . Două fire diferite își îndeplinesc apoi funcțiile și, la un moment dat, bifează a și îl incrementează cu unul. În general, te-ai aștepta ca rezultatul a două fire care adaugă unu la zero să fie doi. De cele mai multe ori, acesta ar trebui să fie cazul. Puteți obține un rezultat diferit dacă ambele fire trec prin această funcționalitate specifică exact la momentul potrivit.

În acest caz, primul fir citește valoarea unui . Înainte ca primul thread să poată incrementa valoarea unui totuși, al doilea thread îl citește. Acum primul thread adaugă unu la zero, dar al doilea thread deja crede că valoarea este zero, adăugând unu la zero. Rezultatul este că valoarea finală a lui a este 1, nu 2.

Cursând spre scenariul cel mai rău caz

Deși exemplul de mai sus ar putea să nu sune deosebit de rău, poate avea efecte dramatice. Ce se întâmplă dacă valoarea lui a selectează modul de funcționare al unei mașini? Ce se întâmplă dacă anumite moduri de funcționare ale acelei mașini pot fi periculoase sau chiar punând viața în pericol?

Nici condițiile de cursă nu trebuie să fie atât de simple. De exemplu, este posibil ca un fir de execuție să citească o secțiune de memorie în același timp în care un alt fir de execuție îi scrie. În acest caz, firul de citire poate obține un amestec ciudat de date atât dinainte, cât și de după. Să presupunem că verificarea este o simplă verificare adevărat/fals.

Dacă variabila a spus adevărat la începutul citirii, dar a fost în curs de a fi suprascrisă cu cuvântul false, rezultatul operației de citire ar putea fi ceva de genul „trlse”. Acest lucru nu este „adevărat” sau „fals”. Nefiind nici una dintre cele două opțiuni într-o alegere binară ar duce aproape sigur la prăbușirea aplicației. Această corupție a memoriei poate duce la multe probleme de securitate, cum ar fi refuzul serviciului și escaladarea privilegiilor.

Închiderea Cursei

A ști ce biți de memorie dintr-un program sunt partajați între diferite fire este esențial pentru a preveni o condiție de concurență. Nu trebuie făcut nimic dacă o variabilă este controlată și accesibilă doar de un singur fir. Dacă două sau mai multe fire de execuție pot accesa o variabilă, atunci trebuie să vă asigurați că toate operațiunile pe acea bucată de memorie sunt finalizate independent una de cealaltă.

Această independență este obținută datorită unei încuietori. În codul unui program, trebuie să puneți o blocare atunci când scrieți o funcție care funcționează pe o bucată de memorie partajată. Această blocare blochează alte fire să acceseze acea bucată de memorie până când blocarea este eliberată.

Lacătul nu este cea mai elegantă dintre soluții. În primul rând, are suprafețe de memorie. De asemenea, poate forța un fir să atârne, așteptând ca un lacăt să fie eliberat. În funcție de situație, blocarea poate să nu fie eliberată o perioadă foarte lungă de timp sau să nu fie eliberată deloc. În cel mai rău caz, deblocarea unei blocări ar putea depinde de ceva care se întâmplă într-un alt fir blocat, ceea ce duce la un impas.

Este esențial să optimizați utilizarea încuietorilor. Puteți controla cât de granulară este blocarea. De exemplu, dacă editați date într-un tabel, puteți bloca întregul tabel sau doar rândul editat. Blocarea întregii mese ar fi o blocare de granularitate grosieră. Minimizează suprasarcina de la implementarea prea multor blocări, dar crește șansa ca un alt fir să fie blocat de blocare. Blocarea doar a rândului ar fi o blocare fină de granularitate. Este mult mai puțin probabil să interfereze cu alte fire, dar înseamnă că vor fi necesare încuietori rupte, crescând supraîncărcarea totală.

Concluzie

O blocare a memoriei este un instrument de cod care este utilizat pentru a asigura operațiunile de atomicitate în memorie într-un mediu cu mai multe fire. Blocând o bucată de memorie înainte de a o opera, puteți fi sigur că nu poate apărea niciun comportament neașteptat din cauza unei condiții de cursă. Blocările de memorie vin cu o suprasarcină de memorie, dar pot provoca și blocare.

Blocarea este locul în care un alt thread încearcă să opereze pe un pemory blocat. Firul stă acolo, blocat până când încuietoarea este eliberată. Acest lucru poate cauza probleme dacă eliberarea blocării necesită un alt fir pentru a face ceva, deoarece se poate bloca înainte de a îndeplini condiția prealabilă de a elibera blocarea care îl blochează. Blocările de memorie pot fi evitate prin scrierea codurilor neblocante. A face acest lucru, totuși, poate fi complex și mai puțin performant decât utilizarea încuietorilor. Nu uitați să lăsați comentariile voastre mai jos.



Leave a Comment

Ce să faci dacă Powerbeats Pro nu se încarcă în carcasă

Ce să faci dacă Powerbeats Pro nu se încarcă în carcasă

Dacă Powerbeats Pro nu se încarcă, folosește o altă sursă de alimentare și curăță-ți căștile. Lasă carcasa deschisă în timp ce încarci căștile.

Canon Pixma MG5220: Scanare Fără Cerneală

Canon Pixma MG5220: Scanare Fără Cerneală

Cum să activezi scanarea pe Canon Pixma MG5220 când ai rămas fără cerneală.

5 Motive pentru care laptopul tău se supraîncălzește

5 Motive pentru care laptopul tău se supraîncălzește

Află care sunt unele dintre posibilele motive pentru care laptopul tău se supraîncălzește, împreună cu sfaturi și trucuri pentru a evita această problemă și a menține dispozitivul răcoros.

Cum să rezolvi codul de eroare GeForce Now 0xC272008F

Cum să rezolvi codul de eroare GeForce Now 0xC272008F

Te pregătești pentru o seară de gaming și va fi una mare – tocmai ai achiziționat „Star Wars Outlaws” pe serviciul de streaming GeForce Now. Descoperă singura soluție cunoscută care îți arată cum să repari codul de eroare GeForce Now 0xC272008F pentru a putea începe din nou să joci jocurile Ubisoft.

Elementele de bază ale imprimării 3D: Sfaturi de întreținere pentru imprimanta ta 3D

Elementele de bază ale imprimării 3D: Sfaturi de întreținere pentru imprimanta ta 3D

Întreținerea imprimantelor 3D este foarte importantă pentru a obține cele mai bune rezultate. Iată câteva sfaturi importante de reținut.

Cum să găsești adresa IP a unei imprimante

Cum să găsești adresa IP a unei imprimante

Ai probleme în a descoperi ce adresă IP folosește imprimanta ta? Te vom învăța cum să o găsești.

Principiile Imprimării 3D: O listă de verificare esențială pentru întreținere

Principiile Imprimării 3D: O listă de verificare esențială pentru întreținere

Menținerea echipamentului tău într-o stare bună este esențială. Iată câteva sfaturi utile pentru a-ți menține imprimanta 3D în condiții de vârf.

Cum să folosești AirPods cu telefoanele Samsung

Cum să folosești AirPods cu telefoanele Samsung

Dacă ești nesigur dacă să cumperi AirPods pentru telefonul tău Samsung, acest ghid te poate ajuta cu siguranță. Întrebarea cea mai evidentă este dacă cele două sunt

Cum se clonează un hard disk

Cum se clonează un hard disk

În era digitală modernă, în care datele sunt un bun valoros, clonarea unui hard disk pe Windows poate fi un proces crucial pentru mulți. Acest ghid cuprinzător

Cum să remediați driverul WUDFRd care nu s-a încărcat pe Windows 10?

Cum să remediați driverul WUDFRd care nu s-a încărcat pe Windows 10?

În timpul pornirii computerului, vă confruntați cu mesajul de eroare care spune că driverul WUDFRd nu s-a încărcat pe computer?