Sperre frei nur lesen Liste in Python?

8

Ich habe einige grundlegende Benchmarks für Leistung und Speicherverbrauch gemacht und ich habe mich gefragt, ob es irgendeinen Weg gibt, die Dinge noch schneller zu machen ...

  1. Ich habe eine riesige 70.000-Element-Liste mit einem numpy ndarray und den Dateipfad in einem Tupel in der besagten Liste.

  2. Meine erste Version übergab eine aufgeschnittene Kopie der Liste an jeden der Prozesse im Python-Multiprozess-Modul, aber es würde die Ram-Nutzung auf über 20 Gigabytes explodieren

  3. Bei der zweiten Version habe ich es in den globalen Raum verschoben und über einen Index wie foo [i] in einer Schleife in jedem meiner Prozesse auf einen gemeinsamen Speicherbereich / CoW-Semantik mit dem Prozesse, so explodiert es nicht die Speicherauslastung (bleibt bei ~ 3 Gigabyte)

  4. Nach den Leistungsbenchmarks / der Ablaufverfolgung scheint es jedoch so, als ob die große Mehrheit der Anwendungszeit jetzt im "acquire" -Modus verbracht wird ...

Also habe ich mich gefragt, ob es irgendwie möglich ist, diese Liste irgendwie in eine Art Lockfree / Read-Only zu verwandeln, so dass ich einen Teil des Acquire-Schrittes beseitigen kann, um den Zugriff noch zu beschleunigen.

Bearbeiten 1: Hier ist die oberste Zeile der Profilerstellung der App

%Vor%

Edit 2: Hier ist ein Beispiel für die Listenstruktur:

%Vor%

Dann soll die SIM-Liste fortan nur noch gelesen werden.

    
Pharaun 20.01.2011, 17:00
quelle

1 Antwort

10

Das multiprocessing -Modul bietet genau das, was Sie brauchen: ein Shared Array mit optionalem Locking, nämlich multiprocessing.Array Klasse. Übergeben Sie lock=False an den Konstruktor, um das Sperren zu deaktivieren.

Edit (unter Berücksichtigung Ihres Updates): Die Dinge sind tatsächlich wesentlich aufwendiger als ursprünglich erwartet. Die Daten aller Elemente in Ihrer Liste müssen im gemeinsamen Speicher erstellt werden. Ob Sie die Liste selbst (d. H. Die Zeiger auf die tatsächlichen Daten) im gemeinsam genutzten Speicher ablegen, spielt keine große Rolle, da diese im Vergleich zu den Daten aller Dateien klein sein sollte. Um die Dateidaten im Shared Memory zu speichern, verwenden Sie

%Vor%

Dabei steht data für die Daten, die Sie aus der Datei gelesen haben. Um dies als NumPy-Array in einem der Prozesse zu verwenden, verwenden Sie

%Vor%

erstellt eine NumPy-Array-Ansicht für die freigegebenen Daten. Um den Pfadnamen gemeinsam zu verwenden, verwenden Sie

%Vor%

wobei Pfad eine normale Python-Zeichenfolge ist. In Ihren Prozessen können Sie auf diese als Python-Zeichenfolge zugreifen, indem Sie shared_path.raw verwenden. Fügen Sie nun (shared_data, shared_path) zu Ihrer Liste hinzu. Die Liste wird in die anderen Prozesse kopiert, die eigentlichen Daten jedoch nicht.

Ich wollte ursprünglich multiprocessing.Array für die aktuelle Liste verwenden. Dies wäre vollkommen möglich und würde sicherstellen, dass auch die Liste selbst (d. H. Die Zeiger auf die Daten) im gemeinsamen Speicher ist. Jetzt denke ich, dass das überhaupt nicht so wichtig ist, solange die tatsächlichen Daten geteilt werden.

    
Sven Marnach 20.01.2011, 17:08
quelle

Tags und Links