AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Container?
Thema durchsuchen
Ansicht
Themen-Optionen

OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Container?

Ein Thema von juergen · begonnen am 15. Okt 2017 · letzter Beitrag vom 27. Okt 2017
Antwort Antwort
Seite 3 von 4     123 4      
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#21

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 23. Okt 2017, 10:47
Wie schon in meiner vorherigen Antwort geschrieben, hatte ich kein Delphi zur Hand und habe den Code "blind" in Notepad++ geschrieben. So wie er in meinem Kopf funktionierte ^^ Dass es da kleinere Unzulänglichkeiten gibt ist ja ganz normal. Da mir konkrete Informationen zur Funktionsweise und Zweck des Programms fehlten, ist mein Beispiel recht generisch konstruiert und kann sicherlich verschlankt werden.

Prinzipiell finde ich Parallelprogrammierung in diesen Zeiten spannender denn je. AMD Ryzen Threadripper kommt mit 16C/32T daher und gefühlt 99,99% aller Delphi-Programme laufen Single-Threaded. Da dauert es nicht mehr lang und die Anwender beschweren sich über lausige Performance trotz Manycore-CPU.

Es gibt ganz tolle Programme, wo einem als Entwickler wirklich das Herz aufgeht wenn man genauer hinschaut und die Threads arbeiten sieht. ACDSee z.B. ist so ein Fall. Die Erzeugung von Thumbnails erfolgt mehrstufig und im Hintergrund. SmartFTP ist noch so ein Beispiel. Hier werden die einzelnen FTP-Loads parallelisiert und können sehr komfortabel im UI über ein SpinEdit auf mehr oder weniger Worker konfiguriert werden. Beides sind m.W. C++ Programme.

IMHO bräuchte es aber noch viel bessere Delphi-MT-Toolkits als bisher verfügbar sind. Denn wie dieses doch wirklich seeeeehr simple Beispiel zeigt, müssen wir immer noch erhebliche Verrenkungen machen um sowas zu parallelisieren.

A) die VCL ist in weiten Teilen immer noch Non-Threadsafe.

B) die RTL ist durch überladene Prozeduren zwar streckenweise Threadsafe, aber eben nicht durchgehend.

C) Die OH wird lästig: In gefühlt jedem zweiten Fall "Embarcadero Technologies verfügt zurzeit über keine zusätzlichen Informationen. Bitte unterstützen Sie uns bei der Dokumentation dieses Themas, indem Sie Ihre Kommentare auf der Diskussionsseite eingeben."

D) FMX wird noch lange Zeit kein Ersatz für die VCL sein, weil es einen großen Teil von Drittanbieter-Komponenten schlichtweg nicht für FMX gibt. Und selbst wenn ist das noch keine Garantie, dass das durchgehend Threadsafe ist.

E) Mir persönlich fehlt es nach wie vor an guten und allgemein verständlichen Büchern und Tutorials zum Thema. Es gibt ein paar schon recht betagte wie dieses hier wo ich nicht mal weiß von wem es ist. Zwar gut erklärt, geht aber nur ganz am Ende und sehr knapp auf die objektorientierte Threadprogrammierung ein.

Mein Fazit: Dringender Handlungsbedarf seitens Embadera.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden

Geändert von Codehunter (23. Okt 2017 um 10:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#22

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 24. Okt 2017, 13:26
Hallo Codehunter,

no offense intended! Ich bin froh über deinen Beitrag!
Ich versuche nur, deinen Code zum Laufen zu kriegen, was ich auch gerade geschafft habe.

Folgende Verbesserungen habe ich noch eingebaut:

1. Start weiterer Threads in AuslesenFertig() mit der folgenden Kondition, da bereits gestartete Threads mit erneutem T.Start zu einer Exception führen:
Delphi-Quellcode:
if ((T.Suspended) and (not T.Finished) and (not T.Started)) then
begin
  T.Start;
  Break;
end;
2. Freigeben der Threads bereits bei Erzeugung konfigurieren:
T.FreeOnTerminate := True;

3. Freigeben der Pointer auf die Records in den Threads mit Dispose():
Delphi-Quellcode:
New(Daten); // Speicherplatz reservieren
try
  DL.Add(sFile, Daten^);
  T := TDateiReaderThread.Create(True); //Thread ist erstmal suspendiert
  T.FreeOnTerminate := True;
  T.FileName := sFile;
  T.OnComplete := DateiEinlesenFertig;
  TL.Add(T);
finally
  Dispose(Daten);
end;
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#23

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 24. Okt 2017, 14:05
no offense intended! Ich bin froh über deinen Beitrag!
Hab ich auch nicht so aufgefasst. Alles ganz entspannt. Mir war klar dass der Code nicht gleich laufen würde.

Ich versuche nur, deinen Code zum Laufen zu kriegen, was ich auch gerade geschafft habe.
Das freut mich.

if ((T.Suspended) and (not T.Finished) and (not T.Started)) then
Das finde ich seltsam. Nicht was du gemacht hast sondern weil T.Suspended und not T.Started nach meinem Verständnis eigentlich niemals beide gleichzeitig TRUE oder gleichzeitig FALSE sein sollten. Die Hilfe zu TThread.Started ist mal wieder außerordentlich hilfreich: "Embarcadero Technologies verfügt zurzeit über keine zusätzlichen Informationen. Bitte unterstützen Sie uns bei der Dokumentation dieses Themas, indem Sie Ihre Kommentare auf der Diskussionsseite eingeben."

Freigeben der Pointer auf die Records in den Threads mit Dispose()
Darauf hatte ich schon gleich im selben Post hingewiesen. Ein bisschen Spaß wollte ich euch ja auch noch übrig lassen... Wobei so wie du das machst, nicht ganz richtig ist. Aber das wirst schon noch merken
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden

Geändert von Codehunter (24. Okt 2017 um 14:08 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von bytecook
bytecook

Registriert seit: 6. Aug 2010
Ort: Dornbirn
151 Beiträge
 
Delphi 11 Alexandria
 
#24

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 25. Okt 2017, 00:32
Nochmal kurz was zu Omnithread

Omnithread hat für mich einige gewaltige Vorteile mitgebracht, insbesonders die Messageimplementierung, und der Fakt, dass alle Aktualisierungen der Gui mittels Messages im Mainthread erfolgen. Kein ausbremsendes Synchronize mehr, wenn man was visuell aktualisieren möchte.
Es braucht je nach Komplexität der Aufgabe definitiv ein paar Tage oder Wochen an Einarbeitungszeit, um effektiv Nutzen aus dem Library zu ziehen. Critical Sections kann man mit OTL in den meisten Fällen recht elegant umgehen, das spart in zeitintensiven Bereichen einige CS Kernelaufrufe.

Das Buch "Parallel Programming with OmniThreadLibrary" von Primož Gabrijelčič, erhältlich unter

https://leanpub.com/omnithreadlibrary

war und ist extrem hilfreich. Download als PDF, EPUB oder MOBI auf Leanpub verfügbar. (Btw, dort gibt es auch ein nettes Nick Bundle: https://leanpub.com/b/nicksdelphibookbundle/)

Den gesamten Buchinhalt kann man auch online lesen ... http://otl.17slon.com/book/chap00.html
Der für mich wichtigste Teil war der Lowlevel Teil ... http://otl.17slon.com/book/chap05.html#lowlevel
Zum besseren Verständnis des Messagings ... http://www.thedelphigeek.com/2008/07...s-otlcomm.html


Das Schöne bei OTL ist, daß man mit den OTLMessages Objekte, respektive Objektinstanzen in der TOmniValue verschicken kann.
Kommunikation zwischen Threads findet mittels TwoWayComm statt, Beispiele sind im Master von Omnithread immer mit an Bord. Vorsicht, die liegen nicht im \Examples, sondern im \Tests Verzeichnis.

PS: Falls ein Demo mit Tokyo nicht startet, einfach FastMM4 aus dem Demo-Projektquellcode auskommentieren...
Peter
Was mache ich, wenn ein Bär meine Frau angreift?
Nichts. Er hat sie angegriffen, soll er doch selber sehen, wie er sich verteidigt.

Geändert von bytecook (25. Okt 2017 um 09:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#25

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 25. Okt 2017, 09:46
OTL muss ich mir unbedingt mal anschauen. Sieht vielversprechend aus. Aber dafür braucht es mehr Zeit als ich im Moment habe.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Benutzerbild von bytecook
bytecook

Registriert seit: 6. Aug 2010
Ort: Dornbirn
151 Beiträge
 
Delphi 11 Alexandria
 
#26

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 25. Okt 2017, 10:14
OTL muss ich mir unbedingt mal anschauen. Sieht vielversprechend aus. Aber dafür braucht es mehr Zeit als ich im Moment habe.
Haha, ja, das kenn ich. Ich hab mir die Zeit quasi auch schmerzhaft aus meinen Projekten sowie Freizeit derb rausschneiden müssen...
Peter
Was mache ich, wenn ein Bär meine Frau angreift?
Nichts. Er hat sie angegriffen, soll er doch selber sehen, wie er sich verteidigt.
  Mit Zitat antworten Zitat
MichaelT

Registriert seit: 14. Sep 2005
Ort: 4020 Linz
555 Beiträge
 
Delphi 10.3 Rio
 
#27

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 25. Okt 2017, 14:29
Ohne die MP3Tags sprich einen Index darüber in einer Datei (DB) zu speichern wird die Sache nicht schnell. Eine relationale Desktop DB egal welcher Ausprägung wir zu langsam für einen Musikplayer.

Wenn du irgendwelche Datenbestände anhängst, dann muss man den Index sowieso immer neu aufbauen. In der Praxis baut der MP3 sammelnde Menschen nicht selbst ein Archiv auf, sondern irgendwer gibt ihm ein 'Medium'.

Du brauchst im Mittel zu lange für die Suche und das Laden. Unserer Erfahrung nach machen Benutzer nicht lange dabei mit, wenn sie ein Buchstaben tippen und es rührt sich nichts .

Spätestens beim Suchen nach Titeln oder Teilen von Titeln bist du weg von der Schüssel.

Bei 'unserem' (nicht meinem im Sinne von meinem Eigentum) Musikplayer kam das Repertoire gleich mit mit manuell eingestellten Fadepunkten usw... Damit hat sich die Frage bezüglich dieses Repertoires nicht gestellt, aber beim Import und der Verwaltung für eine Enduser Version ohne Content.

Ich habe damals Indizes pro Directory gemacht und die konnte ich mergen zur Laufzeit.

Metadaten zu allen Lieder in einer ObjectList zu halten ist vermutlich etwas übertreiben.

15k Dateien ist für ein Musikarchiv eher das untere Limit. Das funktioniert für den Einzelnen, wenn du aber ein allgemeineres Archiv anschaust gehst du über 100k Titel.

Ich hoffe du willst das Programm nicht verkaufen. Den wenigsten ist bewusst, dass selbst wenn man die Lautstärke automatisch halbwegs normiert geht die Klangqualität genauso wie die natürliche Lautstärke verloren.

Zumal ich nicht genau weiß was das Programm macht ... deswegen meine Erläuterung aus der Sicht eines Musikplayers.

Hallo zusammen,
Allerdings dauert das Auslesen der Dateieigenschaften wie z.B. der MP3-Tags weitere 1:50 Minuten. An dem Auslesen der Dateieigenschaften kann ich nichts mehr optimieren.
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#28

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 25. Okt 2017, 16:07
@MichaelT: Das sehe ich eigentlich ganz genauso. Der TE hat das Thema Datenbank ja von vornherein ausgeschlossen, weshalb ich mich auf eine Antwort zur konkreten Frage beschränkt habe. Prinzipiell ist ein multithreaded Datei-Auslesen ja nicht verkehrt. Was man dann aus den gewonnenen Daten macht, steht ja auf einem anderen Blatt.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.174 Beiträge
 
Delphi 11 Alexandria
 
#29

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 25. Okt 2017, 21:15
Hallo Codehunter,
hallo MichaelT,

leider habe ich noch keine Zeit gefunden mich mit Threads zu beschäftigen. Ich denke ich benötige dafür viel Zeit.

Zum Thema Datenbank vs. Daten (Musik-Tags) speichern in ein DevExpress-Grid (letztendlich eine Objectlist):
Es gibt einen sehr guten Player mit SQL-Lite-Datenbank -> MediaMonkey. Das ist quasi die eierlegende Wollmichsau in dem Bereich.

Warum hatte ich mich nun gegen eine Datenbank entschieden?
Das Problem sind die Änderungen an den Musikdateien. Auch der geniale MediaMonkey speichert nicht alle Änderungen in der Musikdatei selbst, sondern in seiner DB.
Weiterhin besteht das Problem, wenn man Musikdateien mit anderen Programmen ändert, dass dann *konsistent* zu synchronisieren *ohne jedes Mal die ganzen Dateien neu zu scannen*.
Aus diesem Grunde habe ich mich gegen eine DB entschieden. Ich speichere die Bilder und Tag-Änderungen *direkt* in den Musikdateien und brauch mich nicht um Synchronisierung kümmern.
Die Suche über das Grid ist vernachlässigbar, also schnell genug wie ich finde. Bei ca. 60.000 Dateien benötigt die Suche weniger wie 1 Sekunde.
Weiterer Vorteil OHNE Datenbank: Da alle Änderungen in den Dateien selbst gespeichert werden, ist der Wechsel zu einem anderen Programm unproblematisch.


Ich habe also nur das Problem des Zeitverhaltens beim Einlesen der Musik-Eigenschaften (Tags).


Aber auch hier habe ich mit Testprogrammen inzw. festgestellt, dass Parallelisierung nur zum Teil hilft. Der limitierende Faktor ist wohl die Festplatte! Wenn ich mit 8 Threads die Dateien einlese von einem (langsamen) NAS-Laufwerk ist das langsamer als mit 4 Threads. Bei meiner SSD sieht es besser aus.

OmniThreadLibrary scheint mir zum einarbeiten leichter zu sein, da es dazu ein Buch gibt und etliche Beispiele. Das werde ich aber erst sehen, wenn ich dazu komme mich mit dem Thema zu beschäftigen.
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#30

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 26. Okt 2017, 08:19
Aber auch hier habe ich mit Testprogrammen inzw. festgestellt, dass Parallelisierung nur zum Teil hilft. Der limitierende Faktor ist wohl die Festplatte! Wenn ich mit 8 Threads die Dateien einlese von einem (langsamen) NAS-Laufwerk ist das langsamer als mit 4 Threads. Bei meiner SSD sieht es besser aus.
Nun ja, alles andere hätte mich auch gewundert. Irgendeinen Grund muss es ja geben, dass SSDs so beliebt sind Es gibt immer limitierende Faktoren (Flaschenhälse). Bei einem NAS sind das noch viel mehr als bei einer lokal eingebauten Festplatte. Ich kenne genug Werbeversprechen mit großen Zahlen und wenn man genauer hinschaut ist alles nur heiße Luft. NAS mit GbE-Anbindung ist inzwischen Usus. Doch wie ist die Schnittstelle im System angebunden? Nicht selten findet man da noch 33 MHz PCI-Busse. Oder der verbaute SoC verdient nicht mal die Bezeichnung "CPU". Dann ist auch noch zu klären, ob die Netzwerkverbindung durchgehend Fullduplex läuft oder nicht - WLAN dazwischen: Schon nur noch Halbduplex.

Thumbs.db - schon mal gehört? Microsoft cached Miniaturansichten von Bilddateien auch in einer Datenbank. Aus den selben Gründen. Ich würde einen Cache in so ein Programm einbauen und zusätzlich eine Benutzerfunktion, welche die Daten in zwei Wegen synchronisiert: Vom Cache in die Dateitags oder umgekehrt. Welche Richtung bei Asynchronität bevorzugt werden soll, würde ich dem Anwender überlassen.

Grundsätzlich stellt sich die Frage: Entwickelst du nur für den Hausgebrauch oder marktorientiert?
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz