Progresul numeric, algoritmic și hardware prin 2011-2012 (Partea I)
Noul calculator, trimis de mama, a fost adus pe 27 iulie 2011, iar în octombrie 2011 s-a terminat îmbunătățirea lui.
-placă de bază ACER, sistem ACER VERITON M490G, cu procesor Intel Core i5-650, 3.2 GHz, pe 64 de biți, 4 threaduri logice (pot să rulez 4 programe deodată), 4 MB cache, 16 GB RAM DDR3-1333, 1 GB video (NVIDIA GeForce 9500GT), HDD HITACHI 1TB + HDD-ul SAMSUNG de mai sus, am pornit pe Windows 7 Home Premium atunci, în 2011.
A fost alt progres important de viteză.
Până la 29-30 septembrie 2012: fondul II avea peste 33 de milioane de numere, RZ.TXT avea câțiva GB de acum, iar fondul 2 avea 22094 de numere.
Am descoperit în acea noapte cum se face instalarea GMP-ului, sub Ubuntu Linux 12.04 LTS, cu configure, make, make install, și am văzut că, orientativ, e de vreo 10 ori mai rapid decât MIRACL.
Atunci am realizat că GMP este o bunătate pe lângă MIRACL-ul cu care stăteam de mult timp, și că trebuie să migrez la GMP făcând fișiere noi și plecând de la Windows la Linux, la GCC. Însemna sfârșitul dominației Borland, Windows, BCC32, MIRACL.
În dimineața de 30 septembrie 2012 eram mulțumit de descoperire. Acolo e C simplu, nu C++ care înseamnă viteză mai mică, asta pentru GMP. În C e mai ușor de scris în fișier, și de citit, apropo de problema cu spațiile albe de la RZ.TXT, deci soluția complicată cu virgulele din RZ avea să dispară acum. În prima săptămână a lunii octombrie 2012 am făcut cod nou și migrare la GMP dinspre MIRACL.
Tipul întreg de la GMP este: mpz_t.
El a trecut pe locul Big-ului de la MIRACL.
mpz_t permite de asemenea relaționarea cu tipurile de date întregi clasice, să se facă operații aritmetice între mpz_t și tipurile clasice, cum a făcut Big la MIRACL. MIRACL a căzut în desuet, în trecut, în arhivă.
Am realizat atunci că la GMP 5.1.0 se pot folosi întregi fără semn pe 32 de biți, în relația cu mpz_t, adică până la 4294967295, în loc de 2147483647, și atunci situația factorilor primi ai numerelor depozitate a devenit:
-3858 de numere prime unsigned long int (Linux GCC);
-1315 numere mpz_t*.
*Asta când sub 2147483648 erau 3785 de numere prime, iar restul de 1388, peste.
M-am mirat că nu pot chiar pe 64 de biți, când compilatorul și biblioteca GMP erau acum pe 64 de biți, față de BCC32.
Din 16 octombrie 2012 am pornit o reformă masivă a funcțiilor folosite pentru cercetarea numerică. Am creat un header special de grupare a acestora (TOLIL.h), unde am pus mai multe funcții care se repetau prin fișiere (a căror extensie devenise .cc prin migrarea la Linux). Am scăzut numărul de fișiere și dimensiunea lor: din CARONTE, CARONTE2+3+4 a rămas numai CARONTE, cu două funcții principale (căutare în fondurile I+II cu coeficienți de legătură mpz_t, respectiv cu coeficienți mici). Adică am concentrat partea de căutare.
De asemenea, prin încorporarea funcțiilor comune în header, au scăzut din dimensiunile fișierelor-sursă rămase. Nu mai avusesem header personal pentru funcțiile folosite.
De asemenea am făcut reformă la indentarea codului (cu probleme mari până atunci).
Am încercat și puțin OOP C++ pentru numere, de exemplu o variantă OOP pentru VECUN.cc, dar așa cum am făcut-o (căutând să refolosesc variabile, să nu fie foarte multe declarate), am constatat viteză mai mică la rulare, deși căutasem economie de variabile (locale), fără exces de globale. Am presupus că programarea cu clase C++ scade viteza, și cum viteza de execuție a fost mereu foarte importantă, am preferat mai departe tot programarea funcțională în locul celei de OOP.
Am făcut înnoire/îmbunătățire la funcțiile de calcul al sumei de divizori, cu câteva variante în funcție de mărimea numerelor.
-SUMADIV() la căutarea în sus, SUMADIV1() la cea în jos, pentru numerele cele mai mari, până la 1900+ de cifre;
-SUM(), SUM1() la numerele de mărime moderată (50->140 de cifre);
-SM(), SM1() pentru cele cu maxim 50 de cifre care nici nu aveau decât numărul 2305843009213693951 ca factor prim peste 32 de biți fără semn, care se putea trata special, și ale căror puteri maxime de 2 erau sub 2^64 (atenție, nu este vorba despre cel mai mare divizor impar aici, ci despre cea mai mare putere de 2; care, mai mică de 64, putea fi tratată special, mai optim, ca număr întreg).
Exponentul puterii de 2 la care se împarte exact un număr mpz_t, numit a, se calculează cu mpz_scan1(a, 0).
Rezultatul reformei a fost ca în noiembrie 2012 codul meu numeric să fie mai ordonat, și reformat, și cu o încercare de deschidere spre OOP (descurajată de impresia proastă despre viteza de execuție).
(va urma)
-placă de bază ACER, sistem ACER VERITON M490G, cu procesor Intel Core i5-650, 3.2 GHz, pe 64 de biți, 4 threaduri logice (pot să rulez 4 programe deodată), 4 MB cache, 16 GB RAM DDR3-1333, 1 GB video (NVIDIA GeForce 9500GT), HDD HITACHI 1TB + HDD-ul SAMSUNG de mai sus, am pornit pe Windows 7 Home Premium atunci, în 2011.
A fost alt progres important de viteză.
Până la 29-30 septembrie 2012: fondul II avea peste 33 de milioane de numere, RZ.TXT avea câțiva GB de acum, iar fondul 2 avea 22094 de numere.
Am descoperit în acea noapte cum se face instalarea GMP-ului, sub Ubuntu Linux 12.04 LTS, cu configure, make, make install, și am văzut că, orientativ, e de vreo 10 ori mai rapid decât MIRACL.
Atunci am realizat că GMP este o bunătate pe lângă MIRACL-ul cu care stăteam de mult timp, și că trebuie să migrez la GMP făcând fișiere noi și plecând de la Windows la Linux, la GCC. Însemna sfârșitul dominației Borland, Windows, BCC32, MIRACL.
În dimineața de 30 septembrie 2012 eram mulțumit de descoperire. Acolo e C simplu, nu C++ care înseamnă viteză mai mică, asta pentru GMP. În C e mai ușor de scris în fișier, și de citit, apropo de problema cu spațiile albe de la RZ.TXT, deci soluția complicată cu virgulele din RZ avea să dispară acum. În prima săptămână a lunii octombrie 2012 am făcut cod nou și migrare la GMP dinspre MIRACL.
Tipul întreg de la GMP este: mpz_t.
El a trecut pe locul Big-ului de la MIRACL.
mpz_t permite de asemenea relaționarea cu tipurile de date întregi clasice, să se facă operații aritmetice între mpz_t și tipurile clasice, cum a făcut Big la MIRACL. MIRACL a căzut în desuet, în trecut, în arhivă.
Am realizat atunci că la GMP 5.1.0 se pot folosi întregi fără semn pe 32 de biți, în relația cu mpz_t, adică până la 4294967295, în loc de 2147483647, și atunci situația factorilor primi ai numerelor depozitate a devenit:
-3858 de numere prime unsigned long int (Linux GCC);
-1315 numere mpz_t*.
*Asta când sub 2147483648 erau 3785 de numere prime, iar restul de 1388, peste.
M-am mirat că nu pot chiar pe 64 de biți, când compilatorul și biblioteca GMP erau acum pe 64 de biți, față de BCC32.
Din 16 octombrie 2012 am pornit o reformă masivă a funcțiilor folosite pentru cercetarea numerică. Am creat un header special de grupare a acestora (TOLIL.h), unde am pus mai multe funcții care se repetau prin fișiere (a căror extensie devenise .cc prin migrarea la Linux). Am scăzut numărul de fișiere și dimensiunea lor: din CARONTE, CARONTE2+3+4 a rămas numai CARONTE, cu două funcții principale (căutare în fondurile I+II cu coeficienți de legătură mpz_t, respectiv cu coeficienți mici). Adică am concentrat partea de căutare.
De asemenea, prin încorporarea funcțiilor comune în header, au scăzut din dimensiunile fișierelor-sursă rămase. Nu mai avusesem header personal pentru funcțiile folosite.
De asemenea am făcut reformă la indentarea codului (cu probleme mari până atunci).
Am încercat și puțin OOP C++ pentru numere, de exemplu o variantă OOP pentru VECUN.cc, dar așa cum am făcut-o (căutând să refolosesc variabile, să nu fie foarte multe declarate), am constatat viteză mai mică la rulare, deși căutasem economie de variabile (locale), fără exces de globale. Am presupus că programarea cu clase C++ scade viteza, și cum viteza de execuție a fost mereu foarte importantă, am preferat mai departe tot programarea funcțională în locul celei de OOP.
Am făcut înnoire/îmbunătățire la funcțiile de calcul al sumei de divizori, cu câteva variante în funcție de mărimea numerelor.
-SUMADIV() la căutarea în sus, SUMADIV1() la cea în jos, pentru numerele cele mai mari, până la 1900+ de cifre;
-SUM(), SUM1() la numerele de mărime moderată (50->140 de cifre);
-SM(), SM1() pentru cele cu maxim 50 de cifre care nici nu aveau decât numărul 2305843009213693951 ca factor prim peste 32 de biți fără semn, care se putea trata special, și ale căror puteri maxime de 2 erau sub 2^64 (atenție, nu este vorba despre cel mai mare divizor impar aici, ci despre cea mai mare putere de 2; care, mai mică de 64, putea fi tratată special, mai optim, ca număr întreg).
Exponentul puterii de 2 la care se împarte exact un număr mpz_t, numit a, se calculează cu mpz_scan1(a, 0).
Rezultatul reformei a fost ca în noiembrie 2012 codul meu numeric să fie mai ordonat, și reformat, și cu o încercare de deschidere spre OOP (descurajată de impresia proastă despre viteza de execuție).
(va urma)
Comentarii
Trimiteți un comentariu