Erster Versuch mit Multiprocessing

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo,

    ich möchte mich in MP einarbeiten. Der erste Versuch ging schonmal gehörig schief: Ich möchte eine Liste erstellen mit Tupeln der Form (k, math.sqrt(k)), wobei k von 1 bis 5000 läuft.

    Mein Code ist:

    Das dauert über 20 Sekunden.

    Was mache ich alles falsch?

    Edit: Das Array bleibt sogar leer. Also habeich überhaupt nicht verstanden wie MP funktioniert. Wo kann ich ansetzen?

  • Hallo,

    also auf die schnelle wäre dies hier mein Lösungsvorschlag:

    Hat jetzt bei mir 5 Sekunden gedauert, hängt aber natürlich von der Hardware ab. Deshalb, wie lange dauert der Code bei dir?

    Was die optimale Anzahl an max_workers ist, hängt von der CPU ab. Deshalb kann eine höhere oder niedirgere Zahl zu besseren Ergebnissen führen.

    Bin hier aber auch nicht wirklich fit, weshalb ich sehr gespannt auf weiter Lösungsvorschläge bin.

    EDIT: An diesem Rechner erziehle ich 4 Sekunden wenn ich max_workers auf 4 reduziere.

    Noch ein kleiner Hinweis, deine for-Schleife geht nur bis 4999

  • und das geht am schnellsten, also ohne Multiprocessing. Dauer: 0:00:00.002991

    Also immer aufpassen, ob es Sinn macht es zu verwenden oder nicht.

    In meinem vorherigen Post Zeile 17, statt extend sollte dort append stehen. Kleiner Fehler.

  • Code
    [...]

    und das geht am schnellsten, also ohne Multiprocessing. Dauer: 0:00:00.002991

    Also immer aufpassen, ob es Sinn macht es zu verwenden oder nicht.

    In meinem vorherigen Post Zeile 17, statt extend sollte dort append stehen. Kleiner Fehler.

    Wahrhaftig. Hätte ich nicht gedacht.

    Na gut, dann werde ich erstmal mein Skript zuende schreiben und dann hier nochmal fragen, ob es sinnvoll ist, da mit MP zu arbeiten.

    Vielen Dank!

  • neuernutzer Ein schönes Beispiel für *keine globalen Variablen*. Prozesse haben ihren eigenen Speicher und jeder Prozess hat seine eigene `wurzeln`-Liste und keiner trägt deshalb irgend etwas in die Liste die in dem Prozess existiert der die Arbeitsprozesse startet und jedem davon eine leere Kopie von `wurzeln` überträgt.

    Und auch der Code hätte mindestens durch einen ``if __name__ == "__main__":`-Guard geschützt sein müssen, wenn er schon nicht sauber in einer Funktion steckt. Unter Linux/Unix funktioniert das zufällig, unter Windows wäre einem das um die Ohren geflogen. Steht auch laut und deutlich in der Dokumentation von `multiprocessing`.

    Es ist ziemlich unsinnig 1250 mal jeweils vier Prozesse zu starten, die dann *eine* Wurzel berechnen, und dann den Prozess wieder beenden. Die Wurzelberechnung von einem Wert ist *sehr* schnell im Gegensatz zu dem ganzen Aufwand der für das starten und abräumen von kompletten Prozessen, dem synchronisieren für jeweils vier Werte, und dem Übertragen der leeren Liste und dem einzelnen Wert zwischen den Prozessen und der Rückgabe vom `None` an den aufrufenden Prozess. Das rechnet sich so gar nicht.

    Die Lösung von Hofei ist schon ein bisschen besser, da werden maximal 12 Prozesse gestartet und nicht ein Prozess pro Wert, und die Werte werden einzeln auf diese 12 Prozesse verteilt. Aber eigentlich will man die Werte für so verdammt kurze Berechnungen nicht einzeln an Prozesse übertragen, sondern einen ganzen Haufen Werte auf einmal an die jeweiligen Prozesse übertragen um die kosten für die Kommunikation klein zu halten.

    Wieder zurück zu `multiprocessing` gibt es dafür einen `Pool`, dem man die ganze Werte als Sequenz übergeben kann, und der die dann in grösseren Teilen an die Prozesse übergibt, und danach die Ergebnisse wieder einsammelt.

    Das geht sehr schnell. Ob schneller als ohne zusätzliche Prozesse wage ich zu bezweifeln. Das braucht halt auch ohne Verteilung so gut wie keine Rechenzeit, also lohnt es sich auch nicht das überhaupt verteilen zu wollen.

    Edit: Es macht auch keinen Sinn hier Tupel zu erstellen, weil `Pool.map()` die Ergebnisse in die richtige Reihenfolge bringt, also die auch alle brav aufsteigend von 1 bis 5000 als ersten Wert im Tupel stehen haben, im Ergebnis.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Danke sehr.

    Wie ich merke bringt es mir derzeit nichts, so tief in dieses Thema einzusteigen. Dafür bin ich im coden einfach zu schlecht.

    Ist es in Ordnung, wenn ich (gerne in einem eigenen Thread) meinen Code komplett poste, und ihr sagt mir, was ich wo verbessern kann? Natürlich mit entsprechenden Erläuterungen von mir. Ich möchte nicht dass der Eindruck aufkommt, ich poste etwas und erwarte, dass ihr damit einfach arbeitet.

    Das wären etwa 150 Zeilen Code.

  • Ist es in Ordnung, wenn ich (gerne in einem eigenen Thread) meinen Code komplett poste, und ihr sagt mir, was ich wo verbessern kann?

    Klar, so hab ich am meisten gelernt, Code gezeigt und nach konstruktiver Kritik gefragt. Versuch aber gleich mal vorab so das Grundlegende zu beachten. Keine globalen Variablen, Pep8 ...

  • Hallo,

    vielleicht könnte man ja noch einwerfen, dass 'time' auch Funktionen zur Messung der Prozessdauer bietet, zum Beispiel process_time

    Der letzte Code von Hofei:

    Code
    Dauer: 0.013281221000000003

    Aus Interesse der gleiche Code, nur mit list-comprehension (weil ich das wirklich gerne nutze)

    Code
    Dauer: 0.009870833999999995

    Und dann noch der multiprocessing-Code von __blackjack__

    Code
    Dauer: 0.039969237000000005

    Alles mit der gleiche Hardware, allerdings ging gerade die Sonne unter 8o

    Grüße

    Dennis

    neuernutzer ich kann mich dem letzten Post von Hofei nur anschließen. So habe ich auch mit Python gestartet und auf diesem Weg lerne ich so auch regelmäßig weiter :thumbup:

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Danke für eure Zeit. Ich habe das ganze dann mal thematisch in einen anderen Thread ausgelagert:

    neuernutzer
    26. Mai 2023 um 22:07

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!