Ich habe drei große Listen. Zuerst enthält Bitarrays (Modul Bitarray 0.8.0) und die anderen beiden enthalten Arrays von ganzen Zahlen.Shared Memory im Multiprocessing
l1=[bitarray 1, bitarray 2, ... ,bitarray n]
l2=[array 1, array 2, ... , array n]
l3=[array 1, array 2, ... , array n]
Diese Datenstrukturen benötigen ziemlich viel RAM (~ 16 GB insgesamt).
Wenn ich 12 Teilprozesse beginnen:
multiprocessing.Process(target=someFunction, args=(l1,l2,l3))
Bedeutet dies, dass l1, l2 und l3 wird für jeden Teilprozess kopiert werden oder werden die Teilprozesse teilen diese Listen? Oder um direkter zu sein, werde ich 16 GB oder 192 GB RAM verwenden?
someFunction liest einige Werte aus diesen Listen und führt dann basierend auf den gelesenen Werten einige Berechnungen durch. Die Ergebnisse werden an den übergeordneten Prozess zurückgegeben. Die Listen l1, l2 und l3 werden nicht von someFunction geändert.
Daher würde ich annehmen, dass die Unterprozesse diese riesigen Listen nicht benötigen und nicht kopieren würden, sondern sie nur mit dem Elternteil teilen würden. Bedeutet das, dass das Programm aufgrund des Kopier-auf-Schreib-Ansatzes unter Linux 16 GB RAM benötigt (unabhängig davon, wie viele Unterprozesse ich starte)? Bin ich richtig oder fehle ich etwas, was dazu führen würde, dass die Listen kopiert werden?
BEARBEITEN: Ich bin immer noch verwirrt, nachdem ich ein bisschen mehr über das Thema gelesen habe. Auf der einen Seite benutzt Linux Copy-on-Write, was bedeutet, dass keine Daten kopiert werden. Auf der anderen Seite ändert der Zugriff auf das Objekt seine ref-count (ich bin immer noch unsicher, warum und was das bedeutet). Aber wird das gesamte Objekt kopiert?
Zum Beispiel, wenn ich somefunction wie folgt definieren:
def someFunction(list1, list2, list3):
i=random.randint(0,99999)
print list1[i], list2[i], list3[i]
Würde mit bedeuten diese Funktion, dass l1, l2 und l3 wird vollständig für jeden Teilprozess kopiert werden?
Gibt es eine Möglichkeit, dies zu überprüfen?
EDIT2 Nach dem Lesen ein wenig mehr und Überwachung der Gesamtspeicherauslastung des Systems, während Teilprozesse ausgeführt werden, scheint es, dass ganze Objekte tatsächlich für jeden Teilprozess kopiert werden. Und es scheint, weil Referenzzählung.
Die Referenzzählung für l1, l2 und l3 ist in meinem Programm eigentlich nicht notwendig. Dies liegt daran, dass l1, l2 und l3 im Speicher verbleiben (unverändert), bis der Elternprozess beendet wird. Bis dahin muss der von diesen Listen belegte Speicher nicht freigegeben werden. In der Tat weiß ich sicher, dass der Referenzzähler über 0 bleibt (für diese Listen und jedes Objekt in diesen Listen), bis das Programm beendet wird.
Nun wird die Frage, wie kann ich sicherstellen, dass die Objekte nicht in jeden Teilprozess kopiert werden? Kann ich die Referenzzählung für diese Listen und jedes Objekt in diesen Listen möglicherweise deaktivieren?
EDIT3 Nur eine zusätzliche Anmerkung. Unterprozesse müssen l1
, l2
und oder irgendwelche Objekte in diesen Listen nicht ändern. Die Teilprozesse müssen nur in der Lage sein, auf einige dieser Objekte zu verweisen, ohne dass der Speicher für jeden Teilprozess kopiert wird.
http://stackoverflow.com/questions/10721915/shared-memory-objects-in-python -multiprocessing Ähnliche Frage und Ihre Antwort. – sean
Erraten durch und noch unsicher über die Antwort. Wird das gesamte Objekt kopiert? Nur ein Teil des Objekts? Nur die Seite mit dem Refcount? Wie kann ich das überprüfen? – FableBlaze
Aufgrund von Copy-on-Write, denke ich, dass Sie nichts Besonderes machen sollten. Warum versuchst du es nicht einfach? – NPE