Preemptives Multitasking

Ich hatte meine Frage im internationalen Bereich gestellt, deshalb jetzt hier erneut. Sorry.
Hallo in die Runde.
Ich muss gestehen, dass ich mir bislang die Language Reference bezüglich der Threads nur oberflächlich angesehen habe. Hat ja auch gereicht, um es zum Laufen zu bringen.
Jetzt habe ich (eher zufällig) mitbekommen, dass die Threads in Xojo ein rein kooperatives Multitasking bieten. Es wird also nicht schneller, wenn ich Arbeit auf mehrere Threads aufteile. :frowning:

Habe ich das korrekt verstanden?

Ich habe bei den MBS-Plugnis den Hinweis auf preemtives Multitasking gefunden. Das scheint mir genau das zu sein, was ich mir eigentlich gedacht hatte. Leider stehe ich mit der Dokumentation irgendwie auf dem Kriegsfuß. Ich finde kein einfaches Beispiel. Gefunden habe ich “CGImageSource Thumbnails Threaded.xojo_binary_project”. Das läuft bei mir jedoch in einen Fehler.

Hat jemand ein Anleitung, wie ich die vorhandenen Xojo-Threads (mit möglichst wenig Aufwand) in MBS-Threads umwandeln kann?

Gruß, Stefan Mettenbrink.


Christian Schmitz:

So habe ich es inzwischen verstanden. Da funktioniert ja auch, der Anwender kann weiterarbeiten. Ist nur nicht, was ich mir wünschen würde. Gerade heute, wo eigentlich jeder Rechner mehrere Cores hat, hätte ich erwartet, dass die Threads dann auch darauf verteilt werden.

Ist das für irgendwann geplant?

MyThread.Run, line 12: This Item does not exist
dim image as CGImageMBS = CGImageSourceMBS.CreateThumbnailMT(file, 0, options)

Kann es an einem veraltetem Plugin liegen? Ich glaube ich habe die letzten beiden Versionen ausgelassen.

[quote]Man kann die Threads auch nicht umwandeln.
Man kann nur einzelne aufgaben durch Threaded Funktionen ersetzen, beim MBS Plugin oft durch MT im Namen gekennzeichnet.[/quote]

Ich hatte gehofft, dass ich lediglich anstelle von “NewThread as Thread” etwas wie “NewThread as ThreadMBS” nutzen könnte.

Verschiebe doch den Thread statt einen neuen auf zu machen!?

Oben rechts im Controls Menü dann auf Change Channel.

CGImageSourceMBS.CreateThumbnailMT ist von v19.1, also bitte auf aktuelles Plugin aktualisieren.

Die MT-Methoden von Christian sind solche, die intern multithreaded laufen, also mit ihrem klassenspezifischen Code. Die kannst du nicht für andere Zwecke kidnappen.

Die einzig offiziell unterstützte Methode, in Xojo echtes Multithreading zu erreichen, besteht im Beschäftigen von Kommandozeilen-Hilfsapps. Diese können jeweils in einer interaktiven Shell laufen und mittels Shell.Write bzw. Print miteinander kommunizieren, oder per IPCSocket.

Eine echte präemptive Thread-Unterstützung in Xojo ohne diese Verrenkungen sehe ich persönlich nicht in den nächsten Jahren kommen. Thomas Tempelmann hat einiges dazu erforscht und auf der letzten MBS-Konferenz präsentiert, ist aber auf wenig Interesse gestoßen.

Es funktioniert doch :wink:
OK, Xojo startet gerade mit den aktuellen Plugins.

Zu spät …

Die Aussage verstehe ich nicht.

Deine Frage im General Channel kannst du normalerweise per Controls Menü in einen anderen Kanal schieben, den für Deutsch.

Ich hätte erwartet, dass Christian eine eigene Threadklasse anbietet, die einfach nur nutzen und mit meinem Code füllen muss.
Inzwischen läuft CGImageSource Thumbnails Threaded (“Test Files” fehlt aber wohl). Dort ist nur einThread vorhanden mit der Super Eigenschaft “BackgroundThreadMBS”.
Reicht es nicht, die Threads in meinem Projekt auf BackgroundThreadMBS umzustellen?

Muss ich mir mal in Ruhe ansehen, muss jetzt leider weg.

ThreadMBS gab’s Mal, aber das war ein Support Albtraum.

BackgroundThreadMBS is nur sinnvoll für die Aufrufe um etwas im Thread auszuführen.

Die Klasse hatte ich bislang nie gesehen, danke für den Hinweis!
Und für die genaue Klärung lasse ich sehr gerne Christian das Wort :wink:

In der Doku zu BackgroundThreadMBS sieht man unten die 4 Call Aufrufe, wofür man das benutzen kann. Sonst kann man die nicht brauchen.

Mit Xojo kommst Du aktuell wohl nicht um Helper Apps herum wenn Du auf mehreren Kernen arbeiten möchtest. Aber es gibt häufig viele weitere Möglichkeiten Projekte für eine zügigere Verarbeitung zu optimieren.

Kann/Magst Du uns mehr über Dein(e) Projekt(e) erzählen? Evtl. gibt es andere Lösungsansätze als nur die Last breiter über den/die Prozessor(en) zu verteilen? :slight_smile:

Mit HelperApps ist preemptives Multitasking möglich. Helperapps sind lästig. Das Debugging ist ebenfalls lästig. Das Übergeben von Daten ist ein kritischer Punkt. Da gibt es ein MemoryMappingMBS oder SharedMemoryMBS (Name?) im allseits beliebten Plugin. Damit stopft man Daten auf der einen Seite rein und die kommen sofort auf der anderen Seite heraus.

Ich hatte mal ein Proof-of-Concept für die Kommunikation meines Hauptprogramms mit einem Hilfsprogramm gemacht, um Daten aus AppleMail zu holen. Das Hauptprogramm hat das Schreiben in die Datenbank gemacht, während das Hilfsprogramm die Daten der nächsten Mail geholt hat. Wahr schon ein gutes Stück schneller. Ich konnte nur nicht dem Benutzer die aktuelle Mailbox sperren, sonst hätte ich das gerne verwendet.

[quote=436547:@Sascha S]
Kann/Magst Du uns mehr über Dein(e) Projekt(e) erzählen? Evtl. gibt es andere Lösungsansätze als nur die Last breiter über den/die Prozessor(en) zu verteilen? :)[/quote]

Kein Problem.
Meine App ist ein Programm zur Ahnenforschung. Da habe ich also haufenweise Datensätze mit Personendaten. Da gibt es eine Plausibilitätsprüfung, die beispielsweise prüft, ob eine Person vor den Eltern geboren wurde, ob es ein Frühgeburt ist, ob als Vater und Mutter dieselben Personen angegeben wurden, etc.
Also haufenweise Prüfungen für alle Datensätze. Diese Prüfung habe ich bereits auf mehrere Threads verteilt, weil ich annahm, das würde dann von unterschiedlichen Prozessorkernen berechnet. Ich sehe hier auch nicht, wo ich hier optimieren kann.

Hier auf eine HelperApp auszulagern, ist auch nicht wirklich das, was ich möchte.

Machst Du das für Millionen von Datensätzen mit aufwendigen Algorithmen??? Wie lange dauert so eine Prüfung denn typischerweise?

Gibt es Möglichkeiten Ergebnisse zwischen zu speichern und als Cache für weitere Prüfungen zu verwenden?

In meinem größten Projekt (ein Inhouse Tausendsassa auf dem der Großteil unserer Arbeit im Unternehmen basiert), habe ich abhängig davon wie oft Daten sich ändern und wie oft diese benötigt werden, verschiedenste Caches (Dictionaries, Memory SQLite Datenbanken, etc.) im Einsatz und konnte damit z.B. dafür sorgen das sich die Arbeit mit 6 (mySQL & MSSQL) Datenbanken und REST & Co API’s, wie Arbeit auf dem lokalen Rechner “anfühlt”. Einige komplexe Vorgänge konnte ich so um den Faktor 200x (kein Scherz) beschleunigen.

Was ich damit sagen möchte ist:

  • stelle sicher das die Prüfungen keine unnötigen Prozesse durchlaufen
  • das keine Prüfung mehr als 1x ausgeführt werden muss
  • speichere Daten zwischen, die weiteren Prüfungen helfen, bis sie nicht mehr benötigt werden oder veraltet sind
  • wenn das Programm nicht vom Benutzer aktiv genutzt wird, nutze die Zeit für weitere Prüfungen mit Thread in höherer Priorität
  • möglicherweise muss nicht jede Prüfung sofort erledigt werden
  • zu “schwierige” Prüfungen oder “unsichere” Ergebnisse könnten evtl. mit Unterstützung des Benutzers gelöst werden

Das sind keine Millionen Datensätze (ich weiß von einem Anwender, der etwa 100.000 Datensätze hat). Da dauert es dann etwa drei Minuten. Aber egal wie lange es dauert, wenn es schneller gehen könnte, möchte man nicht warten.

Vor allem bin ich davon ausgegangen, dass für jeden Thread ein eigenes “Programm” (HelperApp) erzeugt wird und dieses auf einem anderen Core läuft (sofern noch vorhanden). Deshalb habe ich die Datensätze auf 8 Threads verteilt, in der Hoffnung, bei einem 8-Core-Prozessor die Cores gleichmäßig auszulasten und die Berechnungsdauer zu verkürzen.

Nein.
Es sind zwar immer dieselben Prüfungen, aber immer mit anderen Ausgangsdaten.
Selbst wenn dem so wäre. Mir geht es darum, dass ich bisher nicht verstanden habe, dass alle Threads immer auf demselben Core laufen. Wie schon gerade beschrieben, hatte ich erwarte, dass ich mit einem neuen Thread ein “eigenständiges Programm” erzeuge, welches dann auf dem Core läuft, der gerade am wenigsten zu tun hat.

Das Beispiel “CGImageSource Thumbnails Threaded” nutzt auch nur einen Thread. Ich verstehe deshalb noch nicht, wieso das dadurch schneller werden sollte. Verstanden habe ich das Beispiel noch nicht. Das muss ich mir noch mal genauer ansehen. Vor allem, mal die Prozessorauslastung beobachten.

Hast Du schon nachgeschaut, was am lngsten dauert? Hast Du schon Instruments zum Code-Profilen eingesetzt? Der Profiler von Xojo ist recht einfach. Instruments ist nicht wirklich schwierig zu bedienen. Damit sind Bottlenecks recht einfach zu erkennen. So ist z.B. ReplaceLineEndingsMBS entstanden.

Was auch immer hilft, ist ein Fortschrittsfenster. Wenn jemand 100.000 Ahnen hat (wie kommt man zu so vielen Personen???), der mu halt etwas lnger warten.

Verstehe, aber das ist leider ein Fakt der sich mit Xojo wohl auch mittelfristig nicht ändern wird. Also versuchen wir Anregungen für Alternative Ansätze zu geben. :slight_smile: