![]() |
Re: Sehr schneller Primzahl-Finder
@Kara:
Wusst ich's doch :) gerade als Frau kann ich dich da nicht verstehen. Die Frauen die ich in meinem Leben glücklicherweise näher kennen lernen durfte verhielten sich da anders. Das ich nun gerade DICH so anmache hat im Grunde nicht's mit dir persönlich zu tuen. Schau mal wir "leben" hier in einer Community. Das bedeutet vorrangig erstmal das nach Möglichkeit alle Mitglieder dieser Community sozusagen selber ohne "Hilfe" von Aussen, erziehen und regulieren, also demokratisch sozusagen. In jeder solchen "Demokratie" ist Kritik erwünscht und eine freie öffentliche Diskussion eine Notwendigkeit. Das ich nun DICH so persönlich kritisiert habe könnte man auch als Zurechtweisung, erzwingen von Respekt, oder auch nur als "Exempel statuieren" betrachten. Aus meiner persönlichen Sicht ging es mir priori aber nur darum dir zu sagen: "mit mir so nicht !". Es ist also nicht auf deine Person ansich zu beziehen, sondern eher ein Beispiel dafür WO alle anderen hier im Forum bei MIR die Grenzen zu ziehen sind. Und gerade weil ich eben keine Unterscheidung in solchen Dingen zwischen Mann und Frau mache, darf man meine Kritiken nicht persönlich betrachten. EDIT: Aber das sollte jetzt wirklich reichen, vergessen wir's einfach. Gruß Hagen |
Re: Sehr schneller Primzahl-Finder
Zitat:
Anfangs hatte ich nur ein normales Sieb des Eratosthenes entwickelt und später mit einer einfachen Bitkomprimierung verbessert. Dann entdeckte ich folgende Internet-Seite: ![]() Es ist jedenfalls logisch, das es in unserem Code ähnlichkeiten gibt, da wir ja die gleichen strategien bzw methoden zur Berechnung der Primzahlen verwendet habe. Alles andere ist purer zufäll. |
Re: Sehr schneller Primzahl-Finder
Zitat:
Erstaunlich, und eben kein Zufall, ist aber der Punkt das man tatsächlich auf ähnlche Sourcen kommt. In deinem Source sind mir ein par Dinge aufgefallen: 1.) du benutzt Fließkommaarithmetik, diese lässt sich beseitigen 2.) an einigen Stellen benutzt du Integer Arithmetik die sich idealerweise durch schnelle Shifts + Aditionen ersetzen lässt. Du solltest jetzt versuchen auf Basis deines Source noch folgende Features einzuarbeiten: 1.) Berechnung Indexof(Primzahl) 2.) mit 1.) CountOfPrimes := IndexOf(Stop) - IndexOf(Start) 3.) zerlegung des Algos in zwei Teile -> a) Berechnung ob Primzahl ja/nein in Bit Array[] und b) daraus Berechnung der realen Primzahl. Somit benötigt man für 1.) und 2.) zu deren Berechnung nur noch Part a) und nicht mehr Part b) 4.) Initialisierung des Restesiebes mit beliebigem Startwert, statt immer mit 2 beginnend. Dadurch kann der Algo. bei beliebigen Zahlen beginnend anfangen zu scannen. 5.) eventuell das Sieb auf 2^64 erweitern,was aber schon wirklich schwieriger sein wird. Mein Source dazu liegt unfertig auf Halde ;) Gruß Hagen |
Re: Sehr schneller Primzahl-Finder
Zitat:
Ansonsten danke für die Tipps. mfg Phantom1 |
Re: Sehr schneller Primzahl-Finder
Ich rede ja auch nicht von "div 30" sondern "*30"
Delphi-Quellcode:
Und "div 30" liese sich durch "*(1/30)" ersetzen. Allerdings sollte man so'nen Aufwand wirklich nur in den innersten Schleifen treiben.
PrimeBits:=PrimeLen*30;
--> PrimeBits := (PrimeLen * 16 - PrimeLen) * 2; --> asm LEA EAX,[PrimeLen * 16 - PrimeLen] ADD EAX,EAX end; Gruß hagen |
Re: Sehr schneller Primzahl-Finder
Delphi-Quellcode:
ersetze in Num := i*30+s -> Num := ic + s; und ic inkrementierst du in der i Schleife mit +30.
for i:=0 to Trunc(Sqrt(PrimeBits)/30) do
for j:=0 to 7 do if PrimesLUT[i] and (1 shl j)=0 then begin s:=STEMPEL[j]; Num:=i*30+s; Num2:=Num*Num; mbit:=Num2 mod 30; m:=(Num2-mbit) div 30; while m<PrimeLen do begin PrimesLUT[m]:=PrimesLUT[m] or MODS[mbit]; Inc(m, i); Inc(mbit, s); if mbit>29 then begin Dec(mbit, 30); Inc(m); end; end; end; So gäbe es bestimmt noch einige Stellen die succesive auf dies Art und Weise beschleunigt werden können. Gruß Hagen |
Re: Sehr schneller Primzahl-Finder
Delphi-Quellcode:
MODs[mBit] := 1 shl mBit;
PrimesLUT[m]:=PrimesLUT[m] or MODS[mbit];
der Shift dürfte auf heutigen Rechnern schneller ausgeführt werden als eine Lookup Tabelle im Speicher. Gruß Hagen |
Re: Sehr schneller Primzahl-Finder
Delphi-Quellcode:
Sqrt(k+1); was wäre wenn k von Anfang an schon von 0 bis Sqrt(MaxPrime div PrimeBits) laufen würde ?
for k:=0 to MaxPrime div PrimeBits do begin
FillChar(Primes[0], PrimeLen, 0); for i:=0 to Trunc(Sqrt((k+1)*PrimeBits)/30) do Die Schleife I würde dann von 0 bis (k * PrimeBits) div 30 laufen, richtig ? Ergo: in der äußeren Schleife j würde der Endwert durch den Compiler nur einmalig berechnet und in der Schleife j entfällt die langsamme Fließkommaarithmetik komplett und wird durch viel schnellere Integer Arithmetik ersetzt. Natürlich kannst du hier auch wieder einige Mul's einsparen. Schau dir mal meinen Source genauer an. Er macht ja exakt das gleiche wie der deinige, kommt aber ohne Fließkommazahlen aus und benutzt weniger Divisionen. 1.) Fließkomma weg 2.) Divisionen raus 3.) Multiplikationen durch Shift+Adds ersetzen So sollte deine Optimierungsstrategie sein. Gruß Hagen |
Re: Sehr schneller Primzahl-Finder
Zitat:
Zitat:
Zitat:
Zitat:
Was mich jedoch noch interessieren würde, ist wie du die 2,5 sek auf einen P4 1,5GHz gemessen hast? Ich komme da mit einem wesentlich schnelleren CPU auf schlechtere Resultate. Oder hab ich beim messen was falsch gemacht?
Delphi-Quellcode:
mfg
procedure TForm1.Button3Click(Sender: TObject);
var counter: TCounter; i,j: Cardinal; begin counter:=TCounter.Create(RealTime); i:=primes.IndexOf(1, True); j:=primes.IndexOf(500000000, False); for i:=i to j do primes[i]; caption:=floattostr(counter.Stop); counter.Free; end; Phantom1 |
Re: Sehr schneller Primzahl-Finder
probier mal:
Delphi-Quellcode:
Die tatsächliche "Umrechnung" der Bitarrays[] mit Primes[i] ist irrelevant, da die Bitarrays[] intern schon alle Informationen welche Zahlen Primzahlen sind enthalten.
procedure TForm1.Button3Click(Sender: TObject);
var counter: TCounter; i,j: Cardinal; begin counter:=TCounter.Create(RealTime); i:=primes.IndexOf(1, True); j:=primes.IndexOf(500000000, False); // for i:=i to j do // primes[i]; caption:=floattostr(counter.Stop); counter.Free; end; Benutzt du wie in deinem Beispiel .Indexof(5Mio) UND .Primes[i] so misst du die Laufzeit des Algos. ZWEIMAL ! Also entweder so:
Delphi-Quellcode:
was absolut ausreichend ist da die Bitarrays[] intern nur eine andere Darstellung der Primzahlen sind.
StartCounter;
Primes.IndexOf(5Mio, False); StopCounter; Oder so:
Delphi-Quellcode:
alles andere wäre sozusagen unfair da du zweimal die Laufzeit des Algos misst.
StartCounter;
I := 0; while Primes[i] < 5000000 do Inc(I); StopCounter; Gruß Hagen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz