Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Merita un Termostat Smart pentru ...

Sfat achizitie MTB Devron Riddle

Problema mare cu parintii= nervi ...

switch microtik
 Permis categoria B la 17 ani

Sfaturi pentru pregatirea de eval...

Crapaturi placa

cum imi accesez dosarul electroni...
 Momentul Aprilie 1964

Sursa noua - zgomot ?

A fost lansat Ubuntu 24.04 LTS

Pareri apartament in zona Berceni?
 Free streaming SkyShowtime de la ...

Skoda Fabia 1.0 TSI (110 CP)- 19 ...

Mezina familiei, Merida BigNine

The Tattooist of Auschwitz (2024)
 

BigOperation - operatii numere mari

- - - - -
  • Please log in to reply
57 replies to this topic

#19
MihaiProg

MihaiProg

    Member

  • Grup: Members
  • Posts: 345
  • Înscris: 08.02.2016
Adunarea in implementarea aceea este de 12 ori mai rapida ca implementarea mea,
la inmultire diferentele nu sunt asa da mari, banuiesc ca din cauza faptului ca utilizeaza karatsubaMultiply.
Metoda karatsuba este eficienta doar pentru numere colosale daca imi aduc bine aminte.

#20
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,238
  • Înscris: 24.02.2007
Cu ce-ti propui sa continui?

#21
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,238
  • Înscris: 24.02.2007

View PostIvanMihai, on 05 aprilie 2020 - 11:12, said:

Adunarea in implementarea aceea este de 12 ori mai rapida ca implementarea mea,

Pe sistemul meu, dupa masuratori precise, e doar de 2.1x mai rapida decat naive_add al tau.

Printre cauze:
  • Te plimbi prin tot vectorul in GetSign/SetSign
  • Ajungi sa efectuezi impartiri pentru naive_add (in cadrul finalize)
Inca o observatie: cand faci adunare x + y cu returnarea unui z ma astept sa nu modifici x si y, sa ramana constante.

Edited by dani.user, 05 April 2020 - 12:05.


#22
MihaiProg

MihaiProg

    Member

  • Grup: Members
  • Posts: 345
  • Înscris: 08.02.2016

View Postdani.user, on 05 aprilie 2020 - 11:45, said:

Pe sistemul meu, dupa masuratori precise, e doar de 2.1x mai rapida decat naive_add al tau.
Masuratorile mele au inclus initial si convertirea in big integer din string: string_to_vector("3...") respectiv bigint("3...")
aici sunt diferente mari.
Ca valori bigints am utilizat ce ai postat tu intr-un post anterior.
Daca ignori convetirea string_to_vector, de fapt nu este mai rapida ca implementarea mea.

"dupa masuratori precise" - ce intelegi prin masuratori precise???
Ce-i drept eu am utilizat doar:
clock_t time_req;
time_req = clock();
// first_store_add(one, two);
time_req = clock() - time_req;
printf("Orig   took %f seconds\r\n",(float)time_req/CLOCKS_PER_SEC);

Quote

Te plimbi prin tot vectorul in GetSign/SetSign
Ma plimb la inceputul vectorului pana gasesc o valoare diferita de zero: aceasta valoare diferita de zero pastreaza semnul.
De ce contine zerouri la inceput: din moment ce dimesiunea vectorului rezultat este aproximata.
GetSign/SetSign este utilizat doar de cateva ori deci nu ar trebui sa fie diferente mari.

Quote

Ajungi sa efectuezi impartiri pentru naive_add (in cadrul finalize)

Da, adunarea are acelasi "finalize" ca inmutirea la acest punct.

Quote

cand faci adunare x + y cu returnarea unui z ma astept sa nu modifici x si y, sa ramane constante.
Daca te referi la declararea x si y ca const nu o sa fac asta din moment ce este nevoie de valoarea absoluta a lui x si y abs(x)/abs(y) acestea fiind mai usor de calculat direct in x si y prin inlaturarea semnului decat crearea a unui nou vector care pastreaza abs.
La sfarsit seteaza semnul inapoi.

Daca ar fi sa ignor partea cu convertirea din string a biginteger, implementarea pare ok.

#23
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,238
  • Înscris: 24.02.2007
Da, am masurat doar adunarea. Urmeaza sa masor si conversia.

Masuratori precise:
  • Am folosit std::chrono::high_resolution_clock
  • Am rulat adunarea de 1000x intr-o bucla pentru a aduce timpu buclei macar in zona milisecundelor
  • Am rulat de 1000x bucla si am facut o medie
GetSign ia cam 8-9% din timp, nu e chiar neglijabil. S-ar face si mai repede si mai simplu daca ai stoca separat semnul.

Cel mai mult te costa impartirea, o operatie foarte costisitoare. Iar, pentru adunare cel putin, poti scapa foarte usor de ea.

Conversia e cam de 1.4x mai rapida in cazul bigint decat string_to_vector:
  • bigint proceseaza grupe de base_digits pentru a nu da peste
  • tu tii evidenta dupa fiecare caracter daca n-ai dat peste

Edited by dani.user, 05 April 2020 - 14:59.


#24
MihaiProg

MihaiProg

    Member

  • Grup: Members
  • Posts: 345
  • Înscris: 08.02.2016
Am rezolvat problema cu viteza convertirii din string in big integer, mai ramane problema cu viteza adunarii (din moment ce am utilizat aceasi metoda ca la inmutire), si problema cu impartirea (ceva nu este bine cu implementarea mea a impartirii).

@dani.user:
Din moment ce metoda pe care ai utilizat-o pentru masurare este diferita si nu o pot reproduce, vreau sa te rog sa compari scaderea (-) intre implementarea mea si implemetarea gasita pe NET.

#25
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,238
  • Înscris: 24.02.2007
De cam 1.7x mai rapida varianta de pe net. GetSign + SetSign peste 1/3 din timp.

Edited by dani.user, 05 April 2020 - 21:22.


#26
MihaiProg

MihaiProg

    Member

  • Grup: Members
  • Posts: 345
  • Înscris: 08.02.2016
@dani.user: Multumesc mult.
Am reusit sa rezolv totul. Voi revenii cu o noua versiune.

Edited by IvanMihai, 06 April 2020 - 14:56.


#27
MihaiProg

MihaiProg

    Member

  • Grup: Members
  • Posts: 345
  • Înscris: 08.02.2016
Buna. O noua versiune (v2) a acestui program atasata.
Acelasi mod de utilizare ca originalul, doar implementarea s-a schimbat.

Totusi adunarea nu este dacat cu putin mai rapida decat cea din clasa luata de pe NET,
am rezolvat si acum nu mai inmulteste pentru carry (metoda finalize) la adunare,
Scaderea pe de alta parte este de aproximativ doua ori mai rapida decat cea din clasa luata de pe NET,
inca nu inteleg de ce exista asa de mare diferente intre adunare si scadere.

Pe de alta parte inmutirea este mult mult mai lenta ca adunarea/scaderea, si nu stiu daca o voi putea imbunatatii: de exemplu renuntarea la "/" si "%" in impartire - nu stiu daca este chiar si posibil.

GetSign/SetSign este tot acolo, motivul pe care poate fi lent este ca vectorul contine 0 la inceput ceea cred ca poate fi evitat cumva. (nu este facut in versiunea curenta).

Sper ca de data asta cel putin nu mai produce rezultate eronate.
Cateva teste valori si teste viteza nu ar strica.

Attached Files



#28
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,238
  • Înscris: 24.02.2007

View PostIvanMihai, on 07 aprilie 2020 - 17:05, said:

de exemplu renuntarea la "/" si "%" in impartire - nu stiu daca este chiar si posibil.

Baza putere de 2 si transforma compilatorul / si % in operatii pe biti.

#29
MihaiProg

MihaiProg

    Member

  • Grup: Members
  • Posts: 345
  • Înscris: 08.02.2016

View Postdani.user, on 07 aprilie 2020 - 17:40, said:

Baza putere de 2 si transforma compilatorul / si % in operatii pe biti.
Multumesc pentru ajutorul acordat, poate ma insel dar ca timpul metodei void finalize(vector<long long>& res)
este neglijabil. Operatia de inmultire insasi este cea care ia mult timp, ceea ce este logic din moment ce face asta:
vector<long long> res(2 * len);  // result takes twice size
		for (int i = 0; i < len; ++i) {
			for (int j = 0; j < len; ++j) {
				res[i + j] += x[i] * y[j];
			}
		}



#30
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,238
  • Înscris: 24.02.2007

View PostIvanMihai, on 07 aprilie 2020 - 17:05, said:

Scaderea pe de alta parte este de aproximativ doua ori mai rapida decat cea din clasa luata de pe NET,

Tot clasa de pe net e mai rapida pentru scadere. Cam de 1.3x.

GetSign/SetSign tot afecteaza (nu inteleg de ce tii cu dintii de ele). Nici greater_or_equal nu e optim.

#31
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,238
  • Înscris: 24.02.2007
Inmultirea e foarte lenta fiindca ai un algoritm O(N2)

#32
MihaiProg

MihaiProg

    Member

  • Grup: Members
  • Posts: 345
  • Înscris: 08.02.2016

View Postdani.user, on 07 aprilie 2020 - 18:40, said:

Tot clasa de pe net e mai rapida pentru scadere. Cam de 1.3x.
Nu cum pot sa reproduc rezultatul asta??
Este ceva in neregula cu ce am facut eu ???:
clock_t time_req;
time_req = clock();
for (int i=0;i<2768;i++)
{
bigint div = bigint("30194693...");
bigint divby = bigint("280000...");
bigint res = (div)+(divby);
}
//std::cout << res;
time_req = clock() - time_req;
printf("\r\nNew   took %f seconds\r\n",(float)time_req/CLOCKS_PER_SEC);

Am incercat si cu QueryPerformanceCounter - aproximativ acelasi rezultat!

#33
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,238
  • Înscris: 24.02.2007
Masori si parsarea nu doar adunarea.

Ai rulat in mod Debug sau Release?

#34
MihaiProg

MihaiProg

    Member

  • Grup: Members
  • Posts: 345
  • Înscris: 08.02.2016
In debug mode pana acum.
In release mode timpul este mult mult mai mic.
Ceva nu are sens, adica in debug mode vitezele sunt inversate: in release mode sub dureaza cel mai mult, in debug mode sub dureaza cel mai putin. Posted Image

#35
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,238
  • Înscris: 24.02.2007
Masuratorile de timp se fac doar in release. Ce rezultate obtii in release, pentru i < 100000 sa zicem?

#36
MihaiProg

MihaiProg

    Member

  • Grup: Members
  • Posts: 345
  • Înscris: 08.02.2016
for (int i=0;i<332768;i++)
....

add de pe NET: 10.53, 10.73 secunde
add de mine: 12.43, 12.27 secunde
sub de mine: 12.95, 12.79 secunde

Am setat GetSign cu "return 1" si SetSign cu "return;" si timpul este de 12 secunde,
1 secunda ia faptul ca am "vector<long long>" in loc de "vector<int>"

Anunturi

Bun venit pe Forumul Softpedia!

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate