FreePascal // Multithread ?

Pascal, Basic und andere nicht aufgelistete
osculumobscenum
Beiträge: 25
Registriert: Do Okt 31, 2013 9:03 pm

FreePascal // Multithread ?

Beitrag von osculumobscenum » Sa Jan 22, 2022 10:14 am

Hallo zusammen,

ich habe kürzlich spasseshalber ein paar Zeilen in FreePascal geschrieben, um große Primzahlen zu berechnen...

Code: Alles auswählen

program grosse_prim;
 uses crt;
var i,j : qword;
  prim : boolean;

begin
  clrscr;
  writeln;
  writeln('Berechnung grosser Primzahlen');
  writeln('-----------------------------');
i:=123456000;
  repeat
    prim:=true;
    i:=i+1;
    j:=1;
     repeat
         j:=j+1;
         if i mod j=0 then prim:=false;
     until j>= (i-1);

  if prim=true then writeln(i,' ist Primzahl !');

  until i = 123456789;
  repeat until keypressed;
end.

Das ist nichts schwieriges, wie wir schnell sehen und wenn ich mich jetzt gleich beklage, dass alles so langsam geht, dann bin ich mir dessen auch bewusst, dass man in der inneren Schleife nur bis "Wurzel j" rechnen müsste, aber das ist alles gar nicht das Problem.
Das Problem ist, dass ich anhand meines Conky's gesehen habe, dass das Programm nur einen Prozessorkern benutzt, egal, wie lange es rechnet. Ich hätte gerne, dass es alle vier Kerne nutzt.
Es gibt für FreePascal diese TThread-Unit, aber auch nach längeren Recherchen und anschauen einiger Examples sehe ich mich nicht in der Lage, das obige Programm so zu verändern, dass alle Kerne genutzt werden.

Kann mir da vielleicht jemand helfen?
Danke schon im Voraus!

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: FreePascal // Multithread ?

Beitrag von nufan » Do Jan 27, 2022 11:58 am

Nachdem es jetzt schon einige Tage keine Antwort dazu gab, wage ich mich mal (ohne Pascal-Kenntnisse) ran :D
osculumobscenum hat geschrieben:
Sa Jan 22, 2022 10:14 am
Es gibt für FreePascal diese TThread-Unit, aber auch nach längeren Recherchen und anschauen einiger Examples sehe ich mich nicht in der Lage, das obige Programm so zu verändern, dass alle Kerne genutzt werden.
Wo genau liegt das Problem? Weißt du, welchen Teil deines Codes du parallel laufen lassen möchtest?

Ich habe folgende Dokumentation zu TThread gefunden:
https://www.freepascal.org/docs-html/rt ... hread.html
To create a thread, declare a descendant of the TThread object and override the Execute method.
Ist dir dieses Konzept klar?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: FreePascal // Multithread ?

Beitrag von Xin » Do Jan 27, 2022 1:00 pm

Das letzte Mal, dass ich Pascal in den Fingern hatte... da gab es kein Multithreading. :-D

Ich war bei der Frage schon erstaunt, dass es überhaupt noch jemanden gibt, der sich mit Pascal beschäftigt.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

osculumobscenum
Beiträge: 25
Registriert: Do Okt 31, 2013 9:03 pm

Re: FreePascal // Multithread ?

Beitrag von osculumobscenum » Do Jan 27, 2022 6:05 pm

Pascal habe ich halt in meiner Jugendzeit gelernt und aufgrund fortgeschrittenen Alters bleibe ich halt dabei. :-)

Irgendwie möchte ich halt erreichen, dass alle Kerne mitarbeiten, aber die Anwendung
dieser TThread-Unit ist mir schleiherhaft.

Das Konzept mit dem override usw verstehe ich nicht.

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: FreePascal // Multithread ?

Beitrag von nufan » Fr Jan 28, 2022 8:58 pm

Die parallele Ausführung von Code muss explizit formuliert werden. Du kannst dem System nicht einfach deinen sequentiellen Code vorwerfen und automatische Parallelität erwarten. Es gibt sicher auch schon Programmiersprachen und Frameworks die das für dich übernehmen, an dieser Stelle der Geschichte befinden wir uns mit FreePascal aber wohl nicht ;)

FreePascal stellt dir aber immerhin ein paar fertige Bausteine zur Verfügung, damit du nicht jedes Mal das Rad neu erfinden musst. Diese Bausteine werden in Form von Klassen dargestellt und können Daten, aber auch Funktionen enthalten. "TThread" ist eine so eine Klasse, die du verwenden kannst, um Code parallel auszuführen.

Allerdings kann "TThread" ja nicht wissen, welchen Code du parallel ausführen möchtest. Also anstatt den parallel ausgeführten Code als Teil der Klasse "TThread" bereitzustellen, bietet dir "TThread" mit der Methode "Execute" etwas wie eine Schablone an, die du befüllen kannst. Du erweiterst also die Klasse "TThread" und befüllst "Execute". Die gängige Formulierung davon ist, dass du von "TThread" ableitest bzw. erbst und "Execute" überschreibst (daher auch "override") bzw. implementierst.

Das war die sehr abstrakte Einleitung dazu, hoffe das hilft ein wenig.

Dann stellt sich natürlich die Frage, welchen Code du genau parallel ausführen möchtest. Schleifen sind immer ein guter Hinweis, wo etwas parallel ablaufen könnte. Du iterierst z.B. von 123456000 bis 123456789, jeder Durchlauf ist aber für sich unabhängig. Diesen Zahlenbereich könntest du auf deine Prozessor-Kerne aufteilen und parallel abarbeiten.

osculumobscenum
Beiträge: 25
Registriert: Do Okt 31, 2013 9:03 pm

Re: FreePascal // Multithread ?

Beitrag von osculumobscenum » Sa Jan 29, 2022 7:28 pm

Vielen Dank für die ausführliche, wenn auch nach wie vor sehr abstrakte Erklärung! :-)

Mein Ansatz wäre in der Tat gewesen, dass ich den Zahlenbereich, den ich untersuchen will, wirklich in vier Teile aufteile und diese dann jeweils separat mit einem Thread bearbeiten ließe.
Die Tatsache, dass ich mich ein wenig hilflos gefühlt habe die letzten Tage, und die Tatsache, dass ich all das unter Linux mache, haben mich zu folgendem Workaround geführt : Ich habe zuerst einen definierten Zahlenbereich untersucht und die erforderliche Zeit gestoppt.
Im Anschluss habe ich den Bereich in vier Teile unterteilt und mein Programm per "hardcoding" in vier unterschiedliche Programme umgeschrieben, die jeweils ein Viertel des Bereiches untersucht habe. Diese vier Programme habe ich dann parallel in vier verschiedenen Terminalemulationen laufen lassen und jeweils die Zeiten gestoppt und somit paralleles Arbeiten simuliert - es wurden dann auch tatsächlich alle Kerne genutzt. Dadurch, dass die Rechenzeit relativ lange war verglichen mit Start- und Ladezeiten halte ich das Ergebnis für durchaus Aussagekräftig und ... ja... was soll ich sagen? Das parallele Abarbeiten hat sogar etwas länger gedauert, als das einfache Abarbeiten mit nur einem Kern. Ich gehe also inzwischen davon aus, dass es sich nicht wirklich lohnt, viel Aufwand in eine Abarbeitung mit Multithreading zu stecken.

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: FreePascal // Multithread ?

Beitrag von nufan » So Jan 30, 2022 1:56 pm

osculumobscenum hat geschrieben:
Sa Jan 29, 2022 7:28 pm
Das parallele Abarbeiten hat sogar etwas länger gedauert, als das einfache Abarbeiten mit nur einem Kern.
Könntest du das etwas genauer beschreiben? Dass die gesamte parallele Ausführungszeit größer als eine sequentielle Ausführung ist, finde ich wenig überraschend. Die Ausführungszeit eines parallelen Programms würde aber als grobe Richtlinie nur so lange dauern, wie die langsamste Ausführung deiner parallel gestarteten Prozesse (nicht die Summe aller parallelen Prozesse).

osculumobscenum
Beiträge: 25
Registriert: Do Okt 31, 2013 9:03 pm

Re: FreePascal // Multithread ?

Beitrag von osculumobscenum » Di Feb 01, 2022 5:53 pm

Ich muss meine letzte Behauptung zurücknehmen und das Gegenteil behaupten :
In einem Anfall geistiger Umnachtung habe ich tatsächlich die drei einzelnen Zeiten der Programme zusammen gezählt, obwohl sie ja parallel verlaufen sind. Schöner Blödsinn!
Bei korrektem Auswerten sehe ich, dass die Rechenzeit bei Nutzung eines Kerns bei rund 56 Sekunden liegt
("alle Primzahlen zwischen 1 und 150.000" => 56,34 Sekunden)

...während sie bei parallelem ablaufen dreier Programme bei maximal 31,77 Sekunden liegt.
("alle Primzahlen zwischen 1 und 50.000" => 7,11 Sekunden)
("alle Primzahlen zwischen 50.001 und 100.000" => 19,52 Sekunden)
("alle Primzahlen zwischen 100.001 und 150.000" => 31,77 Sekunden)

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: FreePascal // Multithread ?

Beitrag von nufan » Di Feb 01, 2022 10:55 pm

osculumobscenum hat geschrieben:
Di Feb 01, 2022 5:53 pm
("alle Primzahlen zwischen 1 und 50.000" => 7,11 Sekunden)
("alle Primzahlen zwischen 50.001 und 100.000" => 19,52 Sekunden)
("alle Primzahlen zwischen 100.001 und 150.000" => 31,77 Sekunden)
Niedrigere Zahlen erfordern weniger Iterationen in der inneren Schleife. Mit einer besseren Aufteilung der Zahlenbereiche kannst du das Maximum sicher noch senken.

osculumobscenum
Beiträge: 25
Registriert: Do Okt 31, 2013 9:03 pm

Re: FreePascal // Multithread ?

Beitrag von osculumobscenum » So Feb 06, 2022 8:21 pm

Auf jeden Fall hat dieser Versuch aufgezeigt, dass ich nochmal das Ding mit dem Multithread anschauen muss. Möglicherweise werde ich meine sehr spärlichen C-Kenntnisse aufpolieren und mir diese OpenMP-Sache mal zu Gemüte führen, und sei es nur für Benchmark-Zwecke.

Antworten