Autor Beitrag
Lelf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: Sa 11.08.12 22:35 
Seit einigen Jahren schon beschäftige ich mich mit der Implementierung des sogenannten "quadratischen Siebes", dessen Grundzüge im Jahre 1981 von Carl Pomerance vorgestellt wurden. Um die Theorie und Realisation dieses Faktorisierungsalgorithmuses zu erarbeiten, musste ich zunächst die vorhandene Literatur studieren und versuchen sie zu verstehen. Auch gab und gibt es keine Quellcodes, die in Delphi/Pascal geschrieben sind.
Die Grundzüge des Algotithmuses sind klar vorgegeben, aber für die programmtechnische Umsetzung gibt es zahlreiche Wege und ein optimales Konzept ist ein schwieriges Unterfangen.

Wenn ihr Euch mit meinem Quelltext herumschlagen wollt, so bedenkt bitte folgendes:
- die Kommentare sind rahr und nur insofern vorhanden, daß ich mich selbst im Programm zurechtfinde.
- ich dachte nie an eine Veröffentlichung, wurde aber durch die vielen Anregungen im Forum in der letzten Zeit dazu animiert.
- ich bin ein autodidaktischer Hobby-Programmierer. In meiner Jugend gab es in der Schule und im Studium das Fach Computersprachen noch gar nicht oder nur ansatzweise, habt also ein Einsehen mit stylistischen und programmtechnischen Sachen.
- eine Programm-Hilfe gibt es noch nicht. Ihr müsst also selbst herausfinden, was die Buttons so alles bedeuten.
- Bugs sind leider unvermeidlich.

Die hier vorgestellte Version ist das "multiple polynomomial quadratic sieve", eine Weiterentwicklung (Silverman, Montgomery) des Basis-Algos. Es bekommt eine Vielzahl an Units mitgeliefert, um als Demo-Programm direkt lauffähig zu sein. Diese sind als "Beiwerk":
- Programm-Oberfläche
- PowerTest (perfect power test)
- PrimListe (primes bis 10 000 000 werden beim Programmstart automatisch erstellt)
- QS-Parameter (Primzahl-Basis, Sieb-Intervall...)
- Trial-Division, Fermat, Brent-rho, Pollard p-1, Williams p+1
- ECM aus MPArith von Wolfgang Ehrhardt
- Langzahl-Arithmetik
- Algorithmus (Zahlentheoretische Algorithmen)
- Bit-Manipulationen
- Factorial

Im Moment bin ich an einem toten Punkt angelangt und weiß nicht mehr so richtig weiter. Wenn jemand gewillt ist, diese Implementierung weiter voranzubringen, so wünsche ich mir z. B.:
- eine Hash-Funktion, die das Auffinden der large primes verbessert (bisher: Array mit quicksort und binärer Suche)
- Block Lanczos Algo anstelle des gaußschen Eliminationverfahrens
- double large prime variant
- Self-Initialization QS
- Threads
- Assembler-code
- eine bessere Langzahl-Arithmetik
Gar zu hoch sollte die Messlatte aber nicht gelegt werden. Um an die Laufzeiten der Programme wie M-Sieve oder Dario Alpern's Java-Applet heranzukommen, bedarf es noch eines Faktors von mindestens 10. Eine viel zu hohe Hürde.

So, jetzt sind schon einmal einige Schlagwörter gefallen, die zwangsläufig auf Euch zukommen werden. Das Studium damit kann ich niemandem ersparen. Im Internet sind sehr viele Abhandlungen zu finden. Seid gewarnt! Die Beschäftigung mit der Materie ist langwierig und zeitraubend. Aber ich bin sicher, dass es einige Leute gibt, die sich in der Zahlentherorie ganz gut auskennen und Freude an dem Thema finden werden.

Wer nicht so tief in die Materie und den Quellcode einsteigen will, der kann die Units einfach benutzen oder Teile daraus verwenden und verfeinern.


Gruss Lelf
Einloggen, um Attachments anzusehen!

Für diesen Beitrag haben gedankt: Mathematiker
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Sa 11.08.12 23:21 
Hallo Lelf,
das Programm ist absolut beeindruckend. Eine derartig schnelle Faktorisierung mit Delphi habe ich noch nicht gesehen.
Nochmals: ich bin tief beeindruckt. :flehan:
Leider kann ich Deinen Text nicht compilieren. In der UVarint_Q bekomme ich "Interner Fehler: C1093".
Das habe ich noch nie gesehen. Weiß Du, was das ist?
Beste Grüße
Mathematiker

PS: Die Compiler-Schalter {$A8,B-,C-,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W+,X+,Y+,Z1} mag mein Delphi 5 auch nicht. Irgendetwas mache ich wieder falsch.
PS2: Irgendwie hat Delphi 5 einmal UVarint_Q compiliert. Fügt man auch nur ein Leerzeichen ein oder löscht eins, kommt wieder der Fehler? Ich bin am verzweifeln. :eyecrazy:

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Lelf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: So 12.08.12 13:45 
Hallo Mathematiker,

Du machst mit Sicherheit gar nichts falsch, sondern die Delphi-Versionen spielen sich gegenseitig aus. Ich arbeite mit Delphi 7. Auf meinem Rechner liegt noch eine alte 4-er Version herum. Mit ihr habe ich versucht, das Programm zu compilieren. Ging total daneben, mit ähnlichen mir unbekannten Fehlermeldungen. Zuerst solltest Du vielleicht die Compiler-Anweisungen alle löschen. Dann gelten die Einstellungen, die in den Projekt-Optionen auf deinem Rechner gesetzt sind. $Q, $R sollte man in der Test-Phase sowieso immer auf + setzen. Aus Geschwindigkeitsgründen habe ich diese Schalter zurückgesetzt.
Leider kann ich Dir im Moment nicht weiterhelfen. Mit solchen Aufwärts-Abwärts-Versionsproblemen habe ich überhaupt nicht gerechnet. (War auch gar nicht meine Intention.) Ich glaube aber, der schnellste Weg ist, dass Du Dir eine 7-er Test-Version besorgst.

Gruss Lelf

Moderiert von user profile iconNarses: Beiträge zusammengefasst

Das habe ich gerade gefunden:

entwickler-forum.de/...dex.php/t-12929.html

Lelf

Moderiert von user profile iconNarses: Beiträge zusammengefasst

Auch das könnte hilfreich sein:

docwiki.embarcadero....r:_%25s%25d_(Delphi)

Lelf

Für diesen Beitrag haben gedankt: Mathematiker
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 12.08.12 13:57 
Hallo Lelf,
vielen Dank für die Hinweise.
Es ist kurios. Will ich compilieren, kommt der Fehler. Compiliere ich sofort wieder, ohne etwas zu ändern, funktioniert es in 1 von 4-5 Fällen.
Ich werde jetzt einmal Dein Superprogramm mit dem Aribas von Prof.Forster einen "kleinen" Wettkampf austragen lassen. Ich vermute, dass Du schneller bist.
Beste Grüße
Mathematiker

Nachtrag: Leider ist Aribas doch schneller. Das ändert aber nichts daran, dass Du dennoch ein sehr schnelles Faktorisierungsprogramm geschrieben hast.

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: So 12.08.12 17:30 
Nicht, daß negaH (Hagen Reddmann) noch neidisch wird.... ;-)

user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
Es ist kurios. Will ich compilieren, kommt der Fehler. Compiliere ich sofort wieder, ohne etwas zu ändern, funktioniert es in 1 von 4-5 Fällen.


Den Delphicompiler nahm ich bisher als rein determiniert (deterministisch) arbeitendes Proramm wahr.

Das oben veröffentlichte Programm scheint in der Tat exzellent zu sein. Kleiner Kritikpunkt jedoch: Reichlich unübersichtlich, sowohl hinsichtlich der Oberfläche als auch der Ausgabe.

Warum kann die Faktorisierung nicht einfach, wie z.B. in meinem Langzahlentaschenrechner, ihre Ergebnisse in der Art:

2^3
7^15

ausgeben?
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 12.08.12 20:02 
Hallo Lelf,
bei der Eingabe der Zahl 123456789011111111111111 ergibt sich eine Zugriffsverletzung bei der Faktorisierung mit dem quadratischen Sieb in Deiner Original-Exe. Ich kann Dir allerdings nicht sagen, in welcher Methode es auftritt.
Sollte es bei Dir keinen Fehler ergeben, dann muss irgendetwas mit meinem Computer (Prozessor?, Windows Vista?) nicht stimmen. Das wäre auch ein Hinweis auf das merkwürdige Compilerverhalten.
Beste Grüße
Mathematiker

Nachtrag:
Ich habe die fehlerhafte Stelle lokalisiert. In der Methode
function QuadraticSieveVar(const Nstr: string; var Abbruch: boolean; const aus: boolean): string;
tritt der Fehler an der markierten Stelle auf:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
              if(iL2 = 0)then begin //noch kein Partner gefunden, 1. Auftreten
                inc(countLP);
                if(countLP and 1023 = 0)then //mod 1024, reduziert Aufrufe von SetLenLP_lokal
                  if(countLP + 1024 >= high(primesLP))then SetLenLP_lokal;
--> hier tritt ein Rangecheck-Error auf: primesLP[countLP][0]:= largeP;  //unsortiert, large prime von FX[loop]
                primesLP[countLP][1]:= countLP; //Schlüssel zum zugehörigen XwithLP
                diffe_g1[countLP]   := d_g1;    //Differenz zu First_g
                XwithLP [countLP].Assign(Xmm);  //x-relation
                move(factorsArr[0], indexArray[countLP][0], factorscount*sizeOf(integer));
                setLength(indexArray[countLP], factorscount);
                exit;
              end;


Nachtrag 2: Dank Martoks Hilfe ist das Compiler-Problem gelöst. Es war die Code-Optimierung. Nach dem Abschalten kann ich Deinen Text komplett übersetzen.

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Lelf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: So 12.08.12 22:42 
Hallo Mathematiker,

bei mir tritt die Zugriffsverletzung auch auf, aber so kleinen Zahlen sollte man das QS nicht berechnen lassen. Brent-rho kann dies auch schneller. Aber der Fehler darf natürlich nicht auftreten.

PMPQS_69 Number: 123456789011111111111111 (24) BitLength: 77
NUMBER has small prime factors: 23 * 47 * 83 * 2633 *
new Number: 522589081548029 (15)
23 * 47 * 83 * 2633 * 387904981 (Q9) * 1347209 (Q7) ok, X is prime, Y is prime

Mein Programmier-Fehler ist auch schnell gefunden: Er liegt an der Anfangsdimensionierung des LargePrime-Arrays: Normalerweise ist dieses Array sehr gross: > 30000 bei 60-stelligen Zahlen. Beim fortschreitenden Sieben werden immer mehr LP's gefunden, die Grösse des Arrays muss also ständig abgefragt werden. Dies wollte ich reduzieren indem ich folgenden Code einsetzte:

[delphi=(636)]
if(countLP and 1023 = 0)then //mod 1024, reduziert Aufrufe von SetLenLP_lokal
if(countLP + 1024 >= high(primesLP))then SetLenLP_lokal;
[/delphi]

Das ist natürlich tödlich, wenn wie in dem Fall von so kleinen Zahlen das Anfangsarray ein Länge von 320 besitzt. Du musst also die obigen Zeilen durch

[delphi=(636)]
if(countLP >= high(primesLP))then SetLenLP_lokal;
[delphi]

ersetzten, dann ist alles in Ordnung. Danke für den Hinweis.

Gruss Lelf

Für diesen Beitrag haben gedankt: Mathematiker
Lelf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: Mo 13.08.12 14:54 
Hallo,

Genau zu diesen large primes hätte ich nun eine Frage.
Ich würde gern das Array primesLP durch eine hash-Tabelle ersetzen. Dazu erst einmal etwas Theorie:
Die sogenannte FAKTORBASIS bestimmt den Wert der grössten Primzahl pmax, bis zu der im Siebintervall gesiebt wird. (Klingt doof, ist aber so.) Es müssen also y-Werte gefunden werden mit der Eigenschaft, dass der grösste enthaltene Primfaktor von
(y = f(x) = x^2 - N) <= pmax ist. Bei der 59-stelligen Beispielzahl 88352278142985413739122804338971408876797691379345192846343
ist die FAKTORBASIS FB = 4 608 (index der möglichen Primzahlen)
mit der max. Primzahl Bound1= 94 961.

Es müssen also (4608 + 32) sogenannte Relationen mit oben beschriebenen Eigenschaften gefunden weden, die dann in eine Matrix geschrieben werden. Dies entspricht einem Gleichungssystem mit 4640 Gleichungen und 4640 Unbekannten, das mittels Gauß-Elimination gelöst werden kann.

Das Auffinden solcher Relationen ist das Kernstück aller quadratischen Siebe und soll zunächst einmal nicht betrachtet werden. Beim Sieben findet man aber immer wieder Werte, die nur einen Primfaktor enthalten, der grösser als die FAKTORBASIS ist. Dies sind die sogenannten large primes. Wenn man nun eine weitere Relation mit derselben Primzahl findet, lassen sich diese beiden so kombinieren, dass der grosse Faktor wegfällt (er ergibt ja beim multiplizeren ein Quadrat) und eine neue Relation entsteht, die komplett über der FAKTORBASIS zerfällt.

Alle LargePrimes müssen also gesammelt werden, parallel dazu die x-Werte. Beim nochmaligen Auftreten derselben LargePrime müssen die beiden "Index-Stellen" schnell auffindbar sein. Das ist doch die klassische Situation für eine Hash-Tabelle? Kann mir da jemand weiterhelfen? Gibt es eine schnelle Funktion in Delphi?

Mein bisheriger Lösungsweg ist das Sortieren des Arrays mit Index mittels quicksort und dann binärer Suche. Dabei entstehen aber immer wieder folgende Situationen: 1000 LP sind gefunden, es wird sortiert und gesucht, die nächsten 1000 LP fallen an, wieder dasgleiche sortieren und suchen usw. Es wird also mittels quicksort in ein sortiertes Array einsortiert. Das ist glaube ich nicht allzu effizient. (Aber es funktioniert!)

Das Array hat bei der Beispielzahl am Ende eine Grösse von 27.648 und 20.224 largeP wurden gefunden, mit denen 1875 neue Relationen erzeugt werden konnten.

Gruss Lelf
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Mo 13.08.12 17:07 
user profile iconLelf hat folgendes geschrieben Zum zitierten Posting springen:
Mein bisheriger Lösungsweg ist das Sortieren des Arrays mit Index mittels quicksort und dann binärer Suche. Dabei entstehen aber immer wieder folgende Situationen: 1000 LP sind gefunden, es wird sortiert und gesucht, die nächsten 1000 LP fallen an, wieder dasgleiche sortieren und suchen usw. Es wird also mittels quicksort in ein sortiertes Array einsortiert. Das ist glaube ich nicht allzu effizient. (Aber es funktioniert!)


In der Tat gibt es Sortieralgorithmen, die auf die "Aufnahme" (bzw. Hinzufügung) weiterer unsortierter Elementemengen in ein sortierte Menge "intelligent" reagieren, d.h., mit spürbarer Laufzeitverkürzung im Vergleich zu dem Falle, als wäre die gesamte Menge komplett unsortiert. Auf Anhieb fallen mir da Insert(ion)sort und Proportion Extend Sort, evtl. auch Bubblesort ein. Ersteres und letzteres sind nahezu immer grottenlangsam, zweiteres/mittleres kompliziert. Als Ausweichvariante wäre die separate (Vor-)Sortierung der Menge hinzugekommener Elemente und das Verschmelzen beider Teilmengen mit (irgend-)einem Mergealgorithmus möglich (wie er Bestandteil jedes Mergesorts ist). Quelltexte dazu finden sich in meinem Sortierkino reichlich.

Das ist allerdings alles mit viel zusätzlichem Quellcode verbunden -> Fehlerpotential!

Wenn Du es mithin einfach so läßt, wie es derzeit ist, ist das zwar unelegant, aber letztlich tendenziell genausoschnell, und das mit viel weniger Quellcode.

Ergänzung: Bei Bubblesort soll es auch eine diesbezügliche Optmierung geben, siehe www.sortieralgorithm...pplesort/index.html.
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Di 14.08.12 08:33 
Hallo,

alzaimar hat doch eine Unit für hash-Tabellen komponiert mit einem cardinal als key, den man auch durch int64 ersetzen kann.
www.delphipraxis.net...1-hash-tabellen.html

www.delphipraxis.net/1163560-post28.html mpArith von Gammatester ist wohl beliebt.

Gruß Horst
Lelf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: Di 14.08.12 11:09 
Hallo Horst_H,

Vielen Dank für die Hinweise. Da bin ich jetzt für einige Zeit beschäftigt.

Gruß Lelf
Lelf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: So 14.04.13 14:51 
Verbesserte Ausgabe des MPQS:

Mit einem Pentium-4 Rechner mit 3.2GHz und 2.00GB RAM kann man zur Faktorisierung einer zusammengesetzten, semi-primen Zahl mit folgenden Zeiten rechnen:

Dezimal-Stellen ------- h:m:s
40 ------- 0.5s
45 ------- 1s
50 ------- 4s
55 ------- 15s
60 ------- 50s
65 ------- 2m30s
70 ------- 10m
75 ------- 30m
77 ------- 45m
79 ------- 60m
80 ------- 1h30m
85 ------- 5h
90 ------- 20h

Nun sind das keine besonders guten Werte, aber stolz bin ich allemal.

Gruß Lelf.
Einloggen, um Attachments anzusehen!

Für diesen Beitrag haben gedankt: Mathematiker
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 14.04.13 14:55 
Hallo Lelf,
user profile iconLelf hat folgendes geschrieben Zum zitierten Posting springen:
Nun sind das keine besonders guten Werte, aber stolz bin ich allemal.

Keine guten Werte? Das ist das Beste, das ich jemals in Delphi gesehen habe!
Du kannst nicht nur etwas Stolz sein, nein, Du darfst richtig stolz sein.
Gratulation und meine absolute Hochachtung! :zustimm:

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Lelf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: So 14.04.13 15:19 
Eigentlich wünsche ich mir keine Lobpreisungen, sondern Auseinandersetzung mit dem Thema, erziehlte Zeiten auf anderen Rechnern, code-Verbesserungen etc...

Gruß Lelf.
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 14.04.13 15:41 
Hallo,
user profile iconLelf hat folgendes geschrieben Zum zitierten Posting springen:
Eigentlich wünsche ich mir keine Lobpreisungen, sondern Auseinandersetzung mit dem Thema, erziehlte Zeiten auf anderen Rechnern, code-Verbesserungen etc...

Wie Du wünschst. Wie kann ich auch auf die Idee kommen, mich lobend zu äußern. :|

Die Version 74 läuft nach den ersten Tests etwa 10% schneller als Version 69.
Schön ist, dass jetzt z.B. 12111111111111111111111111111111111111111111111111 vollständig zerlegt wird, vorher blieb ein zusammengesetzter Faktor übrig.
Nach meinem ersten Eindruck geht vor allem der letzte Schritt (Matrix auflösen) schneller. Für größere Zahlen muss ich den Rechner erst einmal laufen lassen.
Meine "Lieblingsfaktorisierung" (letzte Zeile)
turing
ist jetzt auf meinem Rechner (1,73 GHZ, Vista) in nur 2,2 s geschafft, 10% schneller.

Nicht so schön ist, dass nach dem Start des Programms die Hälfte des Fensters rechts außerhalb des Bildschirms ist. Ist aber nicht wirklich dramatisch.
Um etwas zum Algorithmus/Quelltext zu sagen, wirst Du wohl auf andere in der EE hoffen müssen (evtl. user profile iconGammatester oder user profile iconHorst_H). Für eine sachliche Einschätzung fehlen mir die fachlischen Voraussetzungen.

Beste Grüße
Mathematiker
Einloggen, um Attachments anzusehen!
_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Lelf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: So 14.04.13 16:44 
Sehr gut gekontert, muss ich schon sagen!

Übrigends, bei einer gänzlich unbekannten Zahl, sollte das Häcken prefactoring[Trial,rho,p-1,ECM]
gesetzt sein, dann geht das eleganter:

_______________________ 14.04.2013 16:48:33
PPMPQS_74 Number: 12111111111111111111111111111111111111111111111111 (50) BitLength: 164
time (trial/rho): 0,096 sec factors: 3 * 439 * 568787 * 23895329 (L8) * 41729771 (L8) * 16213976376227210431149451 (L26) d: 11 z: 2
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 14.04.2013 16:48:33

Gruß Lelf.
Lelf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: Di 21.01.14 21:15 
Bemerkenswerte Verbesserung des MPQS.

Die neue Version hat eine grundlegende Neuerung erhalten. Ausschlaggebend war der Erwerb eines neuen Computers. Da ging alles ohne hinzutun fast
3 mal schneller, obwohl der "Kerl" nur zu 12% ausgelastet war. Klar, mit 8 Kernen ausgestattet will er ja ein wenig zu tun haben. Erste
Überlegung: Threads. Das ging leider ziemlich daneben, da die vielen Zugriffe auf die relevanten Prozeduren sich nicht gut synchronisieren
ließen. Zweiter Versuch: Vier gleiche Programme erstellen; dann soll sich doch das Betriebsytem um die Zuordung der einzelnen Cores kümmern. Die
Daten werden mittels Dateien (auf Festplatte), WM_CopyData (Arbeitsspeicher), Messages und Start-Parameter untereinander ausgetauscht. Beim
Erlernen dieser Techniken war mir unter anderem das Forum hier eine große Hilfe. Und hurra! Es funktioniert:

_______________________ 21.01.2014 15:44:32
PPMPQS_Parallel80.1 Number: 28687466874559422937712059353521086713986783426098673996299663 (62) BitLength: 205
multiplier: 7 LN(Bound1): 11,574049
---> factorbase created.... FB: 5.120 primesFB[3.287] = 65.003 0,015 sec
Bound1 (= maxprime): 106.303
Bound2 (= 100 * Bound1): 10.630.300
max. countLP: 25.600 max. countDLP: 160
lenNN: 207 Bit First_g: 7852598247811 (13)
smallprimes [~10] = -1,2,3,5,7,11,13,19,23,47, ~59,71,83,97,103,109, ... 106303
Target: 54,855 SIEVE_INTERVAL: 65.000 M = 325.000 NUM = 5
---> Programm___4___fertig 6,125 sec PPMPQS 80.4 : $000205C0
---> Programm___3___fertig 5,875 sec PPMPQS 80.3 : $000105E0
---> Programm___2___fertig 6,000 sec PPMPQS 80.2 : $0001060C
process1 completed. (25%) k: 25.445 intervals
checked: 52.004 full relations: 852 ADDIT: 32
LPs: 10.874 partial: 436 pex: 0 cexit: 0
polys: 2.545 all relations: 1288 d_g34: 294.688
---> Ø decomp/sec: 204,056 6,312 sec
---> Abschnitt____1___fertig 6,312 sec
Warte-Schleifen: i:0 j:0 k:0
Laufzeit (Paralleles Sieben): 6,343sec
---> matrix solved. 2,094 sec
---> Versuche: 3 0,078 sec
MPQS-Laufzeit: 8,531sec
1765778392560438446694191181437 (Q31) * 16246357411227365175349327650299 (Q32) ok, X is prime, Y is prime
time: 10,065 sec
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 21.01.2014 15:44:42

_______________________ 20.01.2014 17:48:10
PPMPQS_Parallel80.1 Number: 82933917438829398902227788085804387634811087090390591779002050218842158397629997943 (83) BitLength: 276
multiplier: 23 LN(Bound1): 13,147819
---> factorbase created.... FB: 21.248 primesFB[12.997] = 300.007 0,282 sec
Bound1 (= maxprime): 512.891
Bound2 (= 300 * Bound1): 153.867.300
max. countLP: 169.984 max. countDLP: 42.496
lenNN: 280 Bit First_g: 902125340192027087
smallprimes [~18] = -1,2,3,5,7,13,19,23,29,31,37,43,47,53,67,97,109,113, ~131,137,139,149,163,173, ... 512891
Target: 76,286 SIEVE_INTERVAL: 300.000 M = 2.400.000 NUM = 8
---> Programm___2___fertig 453,281 sec PPMPQS 80.2 : $001004D4
---> Programm___4___fertig 457,844 sec PPMPQS 80.4 : $000F04F0
---> Programm___3___fertig 461,531 sec PPMPQS 80.3 : $000E04FA
process1 completed. (25%) k: 428.801 intervals
checked: 228.620 full relations: 2296 ADDIT: 32
LPs: 145.795 partial: 2418 pex: 829 cexit: 2599
DLPs: 11.961 partial-partial: 606 >Bound2: 104.758 Verlust: 66.735
polys: 26.801 all relations: 5320 d_g34: 4.470.884
---> Ø decomp/sec: 11,493 462,890 sec = 7min 42,890sec
---> Abschnitt____1___fertig 462,890 sec
Warte-Schleifen: i:0 j:0 k:0
Laufzeit (Paralleles Sieben): 7min 43,172sec
---> matrix solved. 157,172 sec = 2min 37,172sec
---> Versuche: 2 0,765 sec
MPQS-Laufzeit: 10min 21,282sec
353664049153660763431583482613403746092793 (Q42) * 234499145834288859621342887257839749933551 (Q42) ok, X is prime, Y is prime
time: 10min 21,367sec
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 20.01.2014 17:58:31

Diese Faktorisierungen wurden durchgeführt mit:
CPU: Intel Core i7 3770K @ 3.50GHz Ivy Bridge 22nm Technologie
RAM: 8,00GB Dual-Kanal DDR3 @ 800MHz

Unter diesen Voraussetzungen können die Programme Zahlen bis C90 innerhalb einer Stunde zerlegen.
Bis C50 benötigt das Programm keinen Parallel-Betrieb:

166920472426053842846893976277232989161492581409 BitLength: 157
190810195915579693084799 (Q24) * 874798496092444663575391 (Q24)
time: 0,348 sec

Die Datei Factorization_PPMPQS_Parallel77_1.exe muß sich zusammen mit
Factorization_PPMPQS_Parallel77_2.exe
Factorization_PPMPQS_Parallel77_3.exe
Factorization_PPMPQS_Parallel77_4.exe
in einem (beliebigen) Verzeichnis befinden. Man braucht nur Factorization_PPMPQS_Parallel77_1.exe starten. Von hier aus werden alle Aktionen
ausgeführt. Wenn die anderen Programme benötigt werden, werden sie automatisch gestartet und beim Verlassen wieder beendet, ebenso wie die
Dateien gelöscht werden, die zum Daten-Austausch im selben Verzeichnis abgelegt wurden. Vorsicht: wenn das Programm abstürzen sollte (was es
natürlich nie tut), bleiben diese Dateien übrig. Es sind maximal 7 Dateien und haben Namen wie LP_Daten.str oder Sieb_Daten.str und können
ziemlich groß werden, einige MByte und müssen dann von Hand gelöscht werden.

Das Hauptprogramm erkennt auch die Zahl der Kerne (hoffentlich): NumberOfLogicalProcessors: 1, 2, 4 oder 8 und startet dementsprechend die
notwendigen Hilfsprogramme. Bei einem Intel Core i5 sind es dann eben nur 2 Programme, die parallel laufen, bei älteren Dual-Core arbeite nur
das Hauptprogramm. Auf meinem alten Laptop benötigt die obige C62-Zahl 56sec.

Zuerwartende Zeiten lassen sich ungefähr so abschätzen (sub-exponentielles Verhalten): Hat man die Berechnungszeit einer bestimmten Zahl
ermittelt, so benötigt ein Zahl mit 3 Dezimal-Stellen(10 Bit) mehr ca. die doppelte Zeit:
C60... 4sec
C63... 8sec
C66...16sec
:
:
C81...512sec = 8min32s

Falls jemand den Quellcode compilieren und kennenlernen will, kann er dies am besten über die beigefügte Projectgroup.bpg erledigen. Unbedingt
in den Projekt-Optionen als Ausgabeverzeichnis für alle 4 Programme(die sich in ...\Abschnitt1 bis ...\Abschnitt4 befinden) das Verzeichnis
...\Ausführen eintragen.

Die Oberfläche von Programm_1 hilft mir sehr bei der Entwicklung des Quadratischen Siebes. Ich benötige die auf den ersten Blick nichtssagenden
Felder, um mit sehr vielen Parametern und zusätzlichen Funktionen arbeiten zu können. Mir ist klar, daß sie für einen Außenstehenden verwirrend
und unübersichtlich wirken. Es ist also nur eine Möglichkeit der Gestaltung.
Nicht alle falschen oder unsinnige Eingaben werden abgefangen. Programmierfehler sind nicht zu vermeiden. Dann kommt eben die Sanduhr oder
bestenfalls eine Fehlermeldung. Einen anderen Anspruch hat sie nicht. Aber ihr habt ja den Quelltext und könnt nach belieben damit spielen.

Gruß Lelf
Einloggen, um Attachments anzusehen!

Für diesen Beitrag haben gedankt: ub60
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 762
Erhaltene Danke: 127



BeitragVerfasst: Mi 22.01.14 00:11 
Irgendwie ist mir dieser Thread bisher entgangen. Ein beeindruckendes Programm!
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 22.01.14 14:05 
Hallo,

Unter wine 1.7.7 braucht es 2,6 ( AMD Phenom X4 3.2Ghz auf Sockel AM2+ 4 Gb DDR2 800 ) :(
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
       1765778392560438446694191181437 (Q31) * 16246357411227365175349327650299 (Q32)  ok,  X is prime,  Y is prime
        time:  26,140 sec
oder
5 mal länger da nur 2 Threads genutzt werden,da wine nur ~1,6 Gbyte bereitstellt.
Zur Laufzeit wurden aber maximal 707 Mb belegt :-(
MPQS-Laufzeit:    49min 48,741sec
       353664049153660763431583482613403746092793 (Q42) * 234499145834288859621342887257839749933551 (Q42)  ok,  X is prime,  Y is prime
        time:  49min 48,893sec
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯  22.01.2014   12:17:46

Witzig zu sehen, dass alle ~10 Sekunden der CPU -Core gewechselt wird ( Linux 3.12.6 ).
Schön, dass das Ergebnis auch gleich ist :)

Gruß Horst
Lelf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42
Erhaltene Danke: 21



BeitragVerfasst: Mi 22.01.14 15:40 
Hallo Horst,

Danke für die Rückmeldung. Hoffentlich hat sich Dein Computer nicht überanstrengt. Mit einem solchen Ergebnis habe ich in etwa gerechnet.
Hast Du denn schon bemerkt, daß ich einen Code-Abschnitt von Dir verwendet habe: in USieb77_Abschnit1.pas, function Int64Mod_Q Zeile 242.
Ist die Dokumentation so in Ordnung?

Gruß Lelf