Saturday, November 25, 2017

Vectorizarea masivelor multidimensionale

Vectorizarea matricelorm este o terminologie cam vrutală prin care s=a căutat o mai bună utilizare a memoriei interne a unui calculator în vremurile de demult când memoria atât internă, cât și memoria externă era o mare problemă. Un calculator IBM 360 considerat de top  prin  august 1969 avea memorie de 4096 Kb și de aici trebuie pornită orice discuție legată de dimensiunea oricărei probleme de rezolvat cu calculatorul. Un sistem de ecuații de maximum 30variabile  și  30 ecuații însemna definirea unei matrice  
DIMENSION A(30,30) 
în FORTRAN ocupa 30 * 30 * 4 bytes adică 3,515 Kb. La un program de adunare a două matrice, fiecare având 100 linii și 100 de coloane se vor defini în programul FORTRAN 
DOUBLE PRECISION A(100,100), B9100, 100), C(100,100)
necesarul de memorie va fi de 234,375 adică aproximativ 235 Kb, adică 23% din disponibilul de memorie al calculatorului. Calculele se fac riguros și destul de exact, dar tot în acea memorie de 1024 Kb trebuie să încapă pe lângă date și programul rezultat după editarea de legături în forma executabilă. Deci în niciun caz nu va fi vorba de dezmățul de memorie care este acum când un calculator modest are memorie RAM de 4 Gb echivalentul a 16.384 de calculatoare IBM 360 din 1969. 
Această situație a impus vectorizarea, adică un procedeu de a face economie de memorie.
În vremurile de dinainte de 1980 despre alocarea de memorie se știa clar că este numai statică. Limbajul ALGOL 67 amintea ceva de blocuri, de alocare și de dealocare dar nu am avut cunoștință de implementări complete ale limbajului acesta. 
În condițiile implementării limbajelor FORTRAN și COBOL era mare deosebire între conceptele de:
- memorie alocată, adică modul cum au fost definite variabilele în program;
- memorie utilizată, adică tot ce se inițializa și se folosea sub controlul instrucțiunilor executabile.
Într-un program FORTRAN se definea un masiv tridimensional
DIMENSION X(20,10,30) 
și se inițializau constantele N cu 10, M cu 15 și H cu 7.
În secvența:
     DO 30 I=1, N
     DO 30 J=1, M
     DO 30 I=K, 7
30 X(I,J,K) = I + K * J
este inițializată numai o parte din masivul tridimensional, ceea ce înseamnă că restul de memorie este nefolosit. Se falculează  gradul de ocupare G = N*M*K / (20*10*30) În cazul concret G = 0,175 adică nu nivel foarte mic.
Dacă se lucrează cu masi.ve având mai multe dimensiuni pentru a calcula exact poziția unui element în masiv formulele arată că trebuie date niște constante. La masivul bidimensional este necesar să se știe cât a fost alocat numărul de coloane ca valoare numerică. Dacă se lucrează cu masive unidimensionale această restricție dispare și lumea preferă să lucreze cu masive unidimensionale. Vectorizarea, acest termen care nu prea există în limba română și preluat brutal din engleză, înseamnă a pune în corespondentă elementele unui masiv bidimensional cu elementele unui masiv unidimensional și a lucra cu masivul unidimensional efectuând tot felul de operații ca și cum s-ar lucra cu masivul bidimensional.
Dacă se consideră un masiv bidimensional
DIMENSION A(10,10)
se inițializează N=5, M=5, se inițializează cumva numai primele 5 linii și primele 5 coloane pentru a calcula suma elementelor de pe diagonala principală se scrie secvența:
     S=0     
     DO 30 I=1, N*M
30 S = S + X(I + (M-1))
Avem bgijă ca să scriem o secvență de vectorizare de forma:
DIMENSION A(10,10), X(100)
...............
      K=1
      DO 30 I=1, N
      DO 30 J=1, M
      X(K) = A(I,J)
30  K=K+1
Discuțiile legate de avantajele vectorizării sunt lungi și avantajele din acele vremuri făceau diferența la apelul de subprograme unde parametrii formali arătau cu mult mai bine decât în cazul în care se scriau masive multidimensionale însoțite de niște constante care dădeau amri bătăi de cap programatorilor care doreau să facă metenanță atunci când cu lucrau cu constante simbolice definite undeva la începutul programului principal în blocuri COMMON sau de folosirea lui EQUIVALENCE.
DIMENSION X(100), B(10,10)
EQUIVALENCE (B(1),X(1))
Pune în corespondență X(10 cu B(1,1), X(2) cu B(2,1)....X(100) cu B(10,10). Se ține seama de regula după care se face linearizarea. Sunt limbaje unde linearizarea se face coloană de coloană, iar altele linearizarea se face linie de linie. Aici am presupus linearizarea coloană după coloană.
Rste o vectorizare la nivel de zone de memorie alocate static, lucru diferit de vectorizarea aceea care ține seama numai de ceea ce s-a inițialozat.







(25 noiembrie 2017)

No comments:

Post a Comment