Autor |
Beitrag |
Tobi482
      
Beiträge: 135
|
Verfasst: So 02.08.09 10:55
Hi Leute,
ich habe in meinem Programm eine Schleife, die ca 95% der Laufzeit in Anspruch nimmt. Das Programm startet, macht etwas Vorarbeit, gelangt dann in die Schleife und danach beendet es sich. Diesen Vorgang möchte ich gerne Beschleunigen. Daher habe ich einen Profiler eingesetzt um ineffiziente Abschnitte zu finden.
Dabei hat sich sich herausgestellt:
-dass die Scheife 95% der Laufzeit beansprucht
-die meiste Zeit davon die Mehtoden ClassCreate und AfterConstruction beanspruchen
Nun zu meinen Fragen:
1. Wie kann ich die Schleife Parallelisieren, da jeder Durchlauf komplett unabhängig von allen anderen ist?
-Gibt es OpenMP für Delphi?
Ich habe bereits die Schleife in zwei Teile geteilt und jede Hälfte einem Thread übergeben. Dies hat die Laufzeit nur in sehr geringen Maßen beeinflusst. Durch optische Abschätzung des Taskmanagers war erkennbar, dass die Totalauslastung fast unverändert (ca. 5-10% mehr) blieb.
2. ClassCreate und AfterConstruction scheinen Methoden aus dem Delphi Framework zu sein. Der häufe Aufruf erfolgt in meiner Vektor Klasse (3D-Vektoren), hier ein kleiner Ausschnitt
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| Function TTVector.Add(v:TTVector):TTVector; begin Result := TTVector.Create( x + v.x, y + v.y, z + v.z); end;
Function TTVector.Sub(v:TTVector):TTVector; begin Result := TTVector.Create( x - v.x, y - v.y, z - v.z); end;
Function TTVector.Mul(s:Single):TTVector; begin Result := TTVector.Create( x * s, y * s, z * s); end; |
Es ist deutlich zu erkennen, dass dort eine Menge Vektoren erstellt werden. Gibt es hier vllt Vorschläge zur Verbesserung?
Mft Tobi Moderiert von Kha: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am So 02.08.2009 um 13:25
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: So 02.08.09 13:24
Für deinen TVector würde ich auf jeden Fall einen Record verwenden, in neueren Versionen kannst du damit trotzdem Methoden und sogar Operatoren benutzen.
Dass die Aufteilung der Schleife auf einem Multicore überhaupt keinen Effekt zeigt, kann allerdings eigentlich nicht sein  . Der Arbeitsaufwand beider Blöcke ist wirklich in etwa gleich groß?
_________________ >λ=
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 02.08.09 13:29
Es gäbe hier 2 Ansätze, die man soweit es geht kombinieren sollte:
1. schnelleren Speichermanager nehmen. FastMM dürfte hier bereits einiges bringen. (Glaub bei neueren Delphi-Versionen der Default)
2. Nutzung einer Vektor-Bibliothek, die keine Memory-Allocation für Vektor-Operationen nutzt. Schau dir hierzu mal die Mathe-Bibliothek bei Omorphia an. Die Funktionen dort sind bzgl. Performance recht nah am Optimum und bedürfen keiner Speicherverwaltung auf dem Heap (wird alles über Records geregelt).
Ansonsten bräuchte man mal ein wenig Quelltext, um ggf. auch andere Dinge noch zu prüfen bzgl. Optimierung.
MfG,
BenBE.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Tobi482 
      
Beiträge: 135
|
Verfasst: So 02.08.09 13:40
WOW ^^
habe jetzt alles auf ein Record umgeändert, uff fantastisch^^
Von 8000ms auf 1500ms ^^ und das Threading hat jetzt Wirkung. Also wirklich aufgeteilt habe ich die Scheife nicht,
sondern es gibt einen Pool mit unabhängigen Aufgaben. Jeder Thread bedient sich dabei von diesem Pool bis er leer ist.
Synchonisiert habe ich dabei mit Enter und LeaveCriticalSection
Erstmal ein großes DANKESCHÖN
jetzt ist es erheblich schneller
Ja ich benutze immer noch Delphi 7 können die höheren Versionen auch noch alle Win32 oder ist das dann schon alles zwingend .Net?
Welche Version empfiehlst du?
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 02.08.09 14:47
Ehrlichgesagt: Ich nutz auch zu großen Teilen noch D7, wenn's unbedingt was aktuelleres sein soll, dann schau dir mal die TurboDelphi's an. Die 2006 und 2009 machen auch beide noch Win32; beachte aber, dass Delphi 2009 vollständig auf Unicode aufsetzt; du also u.U. einige Sachen anpassen musst.
Ach ja: Weitere Zeit spart man (siehe Omorphia), wenn man sich Records als var-Parameter übergeben lässt. In dem Fall erhält die Routine einen Zeiger auf die Struktur, anstatt einer Kopie, die unnötig Zeit verschlingt.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 02.08.09 16:01
Tobi482 hat folgendes geschrieben : | Ja ich benutze immer noch Delphi 7 können die höheren Versionen auch noch alle Win32 oder ist das dann schon alles zwingend .Net?
Welche Version empfiehlst du? |
Alle Delphiversionen können weiterhin Win32, Delphi für .NET ist tot und es gibt stattdessen ein eigenständiges Produkt als Plugin in Microsoft Visual Studio (Delphi Prism).
Delphi 2005 ist die einzige Version, die nicht zu empfehlen ist. Delphi 2006 bzw. Turbo Delphi funktioniert sehr gut und enthält den schnelleren Speichermanager. Zudem sind auch sehr viele Sprachfeatures dazugekommen, von der übersichtlicheren und produktiveren Delphi-IDE selbst ganz zu schweigen.
Und Delphi 2007 und 2009 sind jeweils nochmal deutlich besser, ab Delphi 2009 dann auch wie gesagt mit Unicode und entsprechend erforderlichen Anpassungen, und die IDE ist auch wieder schneller (da war D7 unschlagbar). Ja, und die kommende Version Weaver wird richtig super, die werde ich auch beim Erscheinen direkt kaufen.
An Stelle von Records wäre auch eine Vektor-Klasse denkbar, die immer als Ziel für das Ergebnis mitgegeben wird. Dann muss die nicht immer neu erstellt werden, das würde sicher auch sehr schnell sein. Also immer nur mit den selben Klasseninstanzen arbeiten. Und in der Art kann man auch noch sehr viel mehr optimieren, kommt aber auf den speziellen Quelltext an.
Denn auch mit Records werden diese ja vermutlich immer wieder im Speicher neu reserviert, weshalb auch dabei Zeit drauf geht, wenn auch deutlich weniger.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 02.08.09 17:18
Die Records werden im Stack abgelegt, was keine zusätzliche Zeit benötigt, da die Stackframes i.d.R. sowieso angelegt werden müssen.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
holomorph
Hält's aus hier
Beiträge: 1
|
Verfasst: Fr 06.11.09 15:41
Hallo Tobi (oder Andere denen die Parallelisierung einer Schleife geglückt ist),
kannst du eventuell mir einen Code-Schnipsel zeigen wie man eine Schleife mit Threads in Delphi parallelisiern könnte?
Oder vielleicht mir zusenden? (holomorph@yahoo.de)
Wäre sehr dankbwar weil ich das bräuchte aber leider nicht fit mit Threads bin...
Gruss,
Christian
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Fr 06.11.09 15:55
Hallo und  im DF, holomorph!
oder du könntest dir diverse Tutorials durchlesen und bei Fragen einen Thread im Forum eröffnen. Denn wie heißt es so schön? Selber denken macht kluck!
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
|