|
Programarea calculatoarelor. Elemente fundamentale
1. Instructiune. Program
2. Sisteme de calcul : RISC, CISC
3. Programare liniara, modulara, structurala
Pentru a lucra, un computer trebuie sa primeasca sarcinile respective, exprimate intr-un mod pe care el le poate intelege corect, pentru a le rezolva rapid si corect.
Modul in care computerul intelege ceea ce trebuie facut este sa i se adreseze fractiuni din sarcina pe care trebuie sa o rezolve, inseriate una dupa alta, aceste fractiuni ale sarcinii fiind prezentate intr-un cod accesibil.
Computerul este proiectat si realizat pentru a executa un numar de instructiuni, fiecare instructiune constand dintr-o secventa de biti, in numar bine precizat, fiecare bit din componenta acestei suite avand importanta lui.
Totalitatea instructiunilor executabile direct de un computer formeaza limbajul cod masina.
Cel care da de lucru computerului (programatorul) trebuie sa exprime problemele (pe care vrea sa le rezolve cu ajutorul computerului) intr-o succesiune de instructiuni (pe care le poate executa computerul) care apartin limbajului cod masina.
Indiferent de tipul computerului, forma generala a unei instructiuni, cu cele doua campuri ale sale (cod-operatie si deplasament), pe care o poate executa este prezentata mai jos:
0 1 0... 0 1 0 1 0 0← serie de n biti
n locatii binare → I_I_I_.._I_I
Deoarece unitatea de informatie dintr-un computer este cuvantul, instructiunea va fi continuta intr-unul sau mai multe cuvinte, in functie de modul in care a fost proiectat computerul.
Campul denumit "cod operatie" a fost descris si i se cunoaste semnificatia; campul denumit "deplasament" este cel care va specifica operandul sau lantul de operanzi implicati in derularea instructiunii respective, dar poate semnifica si adresa la care poate fi gasit operandul sau adresa la care se gaseste adresa (si ciclul poate continua de un numar de ori, in general intre 3 ÷ 5) la care se va gasi, in final, operandul.
Procesorul - CPU executa fiecare instructiune printr-o serie de pasi mici, pe care ii prezentam fara a intra in detalii:
- se transfera instructiunea care urmeaza din memorie in registrul de instructiuni CPU;
- se incrementeaza contorul program (PC - program Counter) pentru a indica urmatoarea
instructiune
- dezvoltarea instructiunii in comenzi interioare si comenzi exterioare;
- ducerea din memorie a operanzilor;
- executa instructiunea, trecandu-se la executarea urmatoarei instructiuni.
Aceasta secventa de pasi este denumita ciclul extrage-decodifica-executa (fetch-decode-execute), fiind ciclul esential in functionarea oricarui computer.
Daca instructiunile apartin unui alt tip de limbaj decat limbajul masina se poate concepe un program care sa interpreteze acele instructiuni si sa le aduca in forma de executare.
Acest program se numeste interpreter si este larg folosit.
Computerele mai vachi aveau seturi de instructiuni restranse si simple.
Incercarile de a construi computere tot mai puternice au condus la instructiuni individuale tot mai puternice, mai complexe.
Instructiunile mai complicate au fost mai bune, deoarece uneori executiile unor operatii individuale se por suprapune sau pot fi executate in paralel, folosind echipamente diferite.
Computerele de inalta performanta au ajuns sa aiba mult mai multe instructiuni decat computerele ieftine, pentru care pretul era mai important decat viteza de executie a instructiunilor.
La sfarsitul anilor `50, IBM (Industrial Business Machine), compania care domina total piata computerelor, recunoscand avantajele dezvoltarii unei singure familii de computere care sa execute aceleasi instructiuni, a introdus termenul de arhitectura (architecture) pentru a decsrie caest nivel de compatibilitate.
Familia de computere avea aceeasi arhitectura dar mai multe implementari diferite, capabile sa execute acelasi program, diferente existand doar privitor la pret si viteza de executie.
Tehnica folosirii interpreterelor, care traduceau instructiunile complexe in instructiuni mai simple, executabile direct pe computere mai ieftine a dus la crearea arhitecturii IBM System/360, o familie de computere compatibile.
Calculatoarele mai simple, cu instructiuni interpretate aveau mai multe avantaje, dintre care prezentam pe scurt cateva:
posibilitatea de a corecta pe loc instructiunile incorect implementate sau de a
rezolva deficiente de proiectare ale hardware-ului de baza;
- posibilitatea de a adauga noi instructiuni;
- testarea si documentarea eficienta a instructiunilor complexe.
Cresterea rapida a capacitatilor de prelucrare (perioada anilor `70) a favorizat proiectarea computerelor care foloseau interpretoare de instructiuni.
In paralel cu aceste schimbari, softul si limbajele de programare au avut, de asemenea o evolutie ascendenta.
Revenind la definitia instructiunii, putem preciza: mai multe instructiuni formeaza un program.
Pentru a fi direct executabil, programul trebuie sa fie scris in limbajul cod masina (in forma sa numerica) sau in limbajul de asamblare (colectie de mnemonici - instructiuni, care corespund fiecare in parte, cu instructiunile cod masina), caz in care va fi tradus in limbaj cod masina de programul numit asamblor.
Limbajul de asamblare a fost creat pentru a se putea scrie programele folosind instructiuni denumite prin litere si nu prin cifre, cum este cazul limbajului cod masina.
Daca este scris intr-un alt limbaj, acesta va fi tradus (translatat) de compilator (un alt program care are aceasta functie de a gasi echivalentele respective) si adus in forma executabila.
Redefinim, aici, cele doua notiuni: program sursa - programul scris intr-un limbaj evoluat (mai apropiat de felul de exprimare naturala a omului) si programul obiect - programul rezultat dupa compilarea programului sursa (se mai numeste si program direct executabil).
Dupa cum se stie, mai multe date (data fiind un simbol la care se adauga semnificatia acestuia) pot furniza o informatie; computerele, prin programele lor executa prelucrari de date, ajungand sa scoata in evidenta informatii.
Majoritatea computerelor de astazi prelucreaza date, foarte putine prelucrand informatii, acestea fiind computere pe care lucreaza programe uriase, numite sisteme expert.
Prin anii `80, cercetatorii preocupati cu problema inteligentei artificiale (IA) au creat primele pachete de programe, prin executarea carora, cautau sa se apropie de inteligenta umana.
Un sistem expert este un program care raspunde unor intrebari sau rezolva probleme dintr-un domeniu specific al cunoasterii, folosind reguli logice care deriva din experienta expertului uman, pe care se strduieste sa-l imite.
Au fost obtinute rezultate incurajatoare in domeniul medical, in strategia comunicarii, dar au fost repede descoperite lacune grave in functionarea acestora, in primul rand dependenta puternica a solutiilor date, de marimile care se prezinta la intrarea sistemului.
Desi nu au fost intrerupte cercetarile in domeniu, rezultatele, in ansamblu, nu au corespuns asteptarilor.
Deci, in privinta prelucrarilor informatiilor (asa cum se prelucreaza datele) vor trebui asteptate schimbari majore in primul rand in tehnologie si apoi in strategia soft care trebuie sa le urmareasca pentru a corespunde.
Au aparut in schimb notiuni noi legate de programare, in special de limbajele de programare, cu aplicatii in economie, stiinta si tehnologie.
2. Sisteme de calcul: RISC - Reduced Instructions Set Computer si CISC - Complex
Instructions Set Computer
In anul 1980, un grup de cercetatori de la Berkeley - California au introdus termenul de RISC (Computere cu set redus de instructiuni) proiectand procesoare diferite de cele existente pe piata in acel moment si care nu erau compatibile cu acestea.
Faptul ca nu trebuiau sa respecte compatibilitatea cu produsele existente le-a creat libertatea de alegere a noi seturi de instructiuni care sa maximizeze performanta globala a sistemului de calcul.
Caracteristica principala a acestor procesoare noi era numarul mic de instructiuni disponibile, in general cam 50, in loc de 200 ÷ 500, cate aveau celelalte.
Proiectantii sustineau ca modul cel mai bun de a realiza un computer era sa ai un numar redus de instructiuni simple, care sa se execute intr-un singur ciclu, si anume extragerea a doua registre, combinarea lor intr-un mod oarecare si depozitarea rezultatului intr-un alt registru.
Firma Sun Microsystems, intre anii 1980 si 1987, a definitivat arhitectura SPARC - Scalable Processor ARChitecture, care se bazeaza pe tehnologia RISC, prin care se implementau numai instructiunile de baza, cele mai semnificative si mai utilizate.
Aceasta tehnologie a permis construirea unor computere foarte puternice, care permiteau prelucrarea paralela a mai multor aplicatii.
In opozitie cu computerele RISC erau computerele CISC (computere cu set complex de instructiuni) si care erau cele mai raspandite.
Chiar daca masina RISC avea nevoie de de patru sau cinci instructiuni pentru a face ce facea masina CISC intr-o instructiune, daca instructiunile RISC sunt de 10 ori mai rapide decat instructiunile CISC (in principal pentru ca nu sunt interpretate), masina RISC va castiga.
Trebuie subliniat faptul ca viteza de lucru a memoriei interne a crescut (datorita tehnologiei) si acest fapt a marit avantajul computerelor RISC.
Tehnologia CISC a fost adoptata pentru primele arhitecturi de calculatoare, cand procesoarele devenidera capabile sa execute peste 400 de instructiuni, fiecare instructiune fiind efectuata intr-un numar determinat (dar diferit) de cicluri simple.
Desi avantajele performantelor oferite de tehnologia RISC este evidenta, majoritatea computerelor existente pe piata sunt de tipul CISC, dar ele incorporeaza multe din principiile pe care le-au evidentiat computerele RISC.
Proiectantii de computere trebuie sa urmareasca cu atentie schimbarile pe care le aduce tehnologia; de exemplu, daca viteza de lucru a memoriilor ar creste de 10 ori, ar deveni chiar mai rapide decat CPU, ceea ce ar impune o totala reconsiderare a arhitecturii computerelor.
In permanenta se urmareste atingerea performantelor prin realizarea de compromisuri, mai ales datorita constrangerilor (limitarilor) de tot felul, in primul rand cerinta compatibilitatii cu niste arhitecturi deja existente (aceasta a fost linia de dezvoltare si a hard-ului si a soft-ului, adica noile produse aparute trebuiau sa permita si functionarea programelor concepute tinand cont de dotarea veche a computerelor)
Astfel, s-au stabilit conditii pe care instructiunile unui nou procesor trebuie sa le respecte, din acestea vom cita cateva:
- toate instructiunile sunt executate direct de catre hardware, deci fara interpretare;
- instructiunile trebuie sa fie usor de decodificat, sa aiba un format fix, cu un numar
mic de campuri si cu dimensiuni prestabilite;
- doar instructiunile de citire si de scriere in memorie trebuie sa acceseze memoria,
operanzii fiind transferati in registre destinate acestui scop.
Proiectantii de computere cauta sa imbunatateasca continuu performantele acestora, una din solutii fiind si paralelismul in executarea instructiunilor.
Acesta consta in executarea mai multor instructiuni in acelasi timp; de aici se obtine si o crestere a vitezei de prelucrare, la o frecventa a ceasului computerului (frecventa interna) data.
Paralelismul apare in doua forme generale:
- la nivelul instructiunilor si
- la nivelul procesorului.
In prima, paralelismul este exploatat in cadrul instructiunilor individuale, pentru a face computerul sa lanseze in executie mai multe instructiuni pe secunda; in cea de-a doaua forma de paralelism, mai multe CPU-uri lucreaza impreuna la rezolvarea aceleiasi probleme.
Fiecare dintre cele doua abordari are anumite avantaje care au dus la stabilirea de tehnologii soft si hard moderne.
Paralelismul la nivelul instructiunilor a dus la aparitia notiunilor de banda de asamblare a instructiunilor (instructions pipeline) si computere superscalare (arhitecturi superscalare), adoptata de mai toate computerele moderne.
Prezentam schema unui procesor superscalar cu cinci unitati functionale (s1 ÷ s5)
Ideea procesorului superscalar este ca segmentul s3 poate lansa instructiunile mult mai repede decat le poate executa segmentul s4, deoarece toate unitatile functionale din acest segment au nevoie de mai mult timp decat un ciclu de ceas pentru a-si termina treaba (pot exista mai multe UAL-uri - unitati aritmetice si logice)
Paralelismul la nivelul procesorului aduce mai mari cresteri ale vitezei de executie.
Multe din problemele din domeniul stiintelor au o structura foarte regulata, adesea aceleasi calcule fiind repetate pe seturi diferite de date in acelasi timp, ceea ce face potrivite pentru procesarea paralela.
Pentru a executa rapid programe stiintifice de dimensiuni mari au fost folosite doua metode, desi foarte asemanatoare:
- extensie pentru un procesor (multiprocesoare) si
- calculator paralel (multicalculatoare).
Multiprocesorul este primul sistem paralel cu mai multe procesoare (CPU) complet folosite, partajand o memorie comuna, coordonate prin soft (sistem de operare) pentru a nu exista conflicte in procesare.
Prezentam, mai jos, schema corespunzatoare multiprocesorului:
Multiprocesoarele cu un numar mic de procesoare sunt relativ usor de construit, cele cu mai mult de 64 de procesoare ridica multe probleme legate de accesul la memorie.
De aceea au fost construite sisteme cu mai multe computere, numite multicalculatoare.
Redam, mai jos, schema unui multicalculator (multiprocesor):
CPU-urile comunica intre ele prin mesaje trimise de la unul la altul, acestea trecand de la un CPU la altul pana isi atinge destinatia, timpii de transmisie fiind destul de mici.
S-au realizat multiprocesoare cu sute de mii de procesoare si se testeaza unitati cu peste un milion de procesoare.
Pentru ca multiprocesoarele sunt usor de programat si multicalculatoarele sunt usor de construit se cerceteaza proiectarea unor sisteme hibride care sa combine avantajele amandorura.
3.Programare liniara, modulara, structurala
Aparitia primelor calculatoare electronice a constituit un mare salt in directia automatizarii activitatilor umane.
La inceput, calculatoarele au fost programate in limbaj masina, activitate foarte dificila care a dus rapid la inventarea limbajelor de asamblare si apoi, a celor evoluate (din ce in ce mai apropiate de limbajul natural al omului).
Dar, limbajele evoluate nu au dus automat la cresterea eficientei muncii de programare.
Cresterea complexitatii programelor elaborate pentru problemele diferitelor domenii ale activitatii umane, precum si necesitatea obiectiva a modificarii, adaptarii acestor programe la conditiile noi, aflate intr-o continua schimbare, ale vietii sociale au fost factori care au ingreunat suplimentar munca de programare.
Cresterea performantelor calculatoarelor, raspandirea acestora si folosirea lor in toate domeniile de activitate au marit complexitatea problemelor pe care trebuia sa le rezolve calculatorul.
Ca exemple de programe complexe mentionam sistemele de operare, compilatoarele, sistemele de gestiune ale bazelor de date.
Aceasta crestere a complexitatii problemelor a avut doua urmari: a trebuit sa se treaca de la programarea liniara (scrierea secventiala a instructiunilor) de catre un singur programator, la organizarea unor colective de specialisti in analiza si programare pe de o parte si la schimbarea strategiei muncii de programare, la cautarea unor modalitati adecvate de specificare a problemelor.
Chiar termenul de program (programare) a suferit schimbari in scurta istorie a informaticii.
Prin anii `60, prin program se intelegea transcrierea unui algoritm (exprimat in termenii unor scheme logice) intr-un limbaj de programare.
Acum se pune problema scrierii unor pachete (sisteme) de programe pentru a se rezolva o problema complexa in orice domeniu de activitate.
Odata cu aparitia limbajului FORTRAN - 1956, datorita posibilitatii de folosire a subalgoritmilor (subdiviziuni ale algoritmilor) in programare si compilarea lor separata, apare si programarea modulara.
Mai departe, compilarea separata a dus la aparitia bibliotecilor de programe, o componenta importanta a programelor sistem.
Programarea modulara consta in descompunerea unei probleme complexe (exprimata printr-un algoritm principal) in subprobleme, fiecareia corespunzandu-i un subalgoritm (modul).
Algoritmul de rezolvare al intregii probleme va fi obtinut prin asamblarea acestor subalgoritmi (module).
Problema care a impiedicat sistematizarea mai multor module de program consta in numarul mare de instructiuni GO TO (salt la o alta adresa, pentru executarea unei alte secvente de program si revenirea la secventa principala).
Edsger Dijkstra, in anul 1968, a propus modalitatea programarii structurate, care urmarea printre altele si eliminarea folosirii instructiunii de salt GO TO, sustinand ca logica unui program este o structura compusa din substructuri similare, modurile lor de combinare fiind limitate ca numar.
Mai precis, el a aratat si ulterior s-a demonstrat ca orice schema logica a unui program poate fi formata utilizand trei structuri logice (baza programarii structurate):
- secventiala sau liniara;
- structuri de selectie - alternative si
- structuri iterative - iterative.
Programarea structurata este adeseori asociata cu perspectiva sus/jos (top/down) asupra structurii logice a programului (insemnand ca inceputul secventei program este deasupra, sus si parcurgerea se face liniar coborand, pas cu pas).
Incepand din 1970, programarea structurata a devenit foarte populara, poate datorita si limbajului de programare Pascal, care era in acea perioada destul de raspandit.
Limbajele de programare care pot fi folosite cu usurinta pentru programarea structurata sunt: ALGOL, Pascal, PL/I, ADA.
Acceptarea programarii structurate nu a fost unanima, dar majoritatea cercetatorilor din domeniu o considera ca fiind o solutie buna si care trebuie urmata.
Mai mult, limbaje vechi, care nu aveau facilitatile programarii structurate, au fost revizuite si adaptate programarii acestor structuri, cum sunt FORTRAN, COBOL, BASIC.
Programarea structurata este considerata ca un premergator al programarii orientata pe obiect.
Chestionar
9. Cum se definesc computerele RISC si CISC?
10. Cum definim programarea liniara, modulara si structurata?
11. Care sunt structurile logice care formeaza baza programarii structurate?