2016-05-02 4 views
2

Ich versuche, die folgende for-Schleife parallel zu implementieren, um ein Wörterbuch zu initialisieren.Gibt es in Julia so etwas wie SharedDict?

heavy=Dict() 
for item in list 
    heavy[item[1]]=10000000 
end 

Wo list ist eine Liste von Listen und jedes Element hat drei Elemente.

Ich war so etwas wie dies versucht:

heavy=Dict() 
@parallel for item in list 
    heavy[item[1]]=10000000 
end 

aber es hat nicht funktioniert. Beim Lesen der documentation habe ich etwas namens SharedArrays gefunden, das das Problem lösen würde. Es ist jedoch nicht klar, wie dasselbe zu tun ist, aber andere Datenstrukturen wie Dict() oder Set() zu verwenden. Vielen Dank im Voraus.

+0

Was meinst du, es hat nicht funktioniert? Mit einer Liste von Listen mit 1, 2 und 3 in den ersten Slots, bekam ich ein Wörterbuch Mapping 1, 2 und 3 bis 10000000. –

+0

Ich bekomme ein leeres Dict. Heavy: Dict {Any, Any}() –

+0

Sie haben recht, ich habe Julia ohne irgendwelche Worker-Prozesse ausgeführt. Ich sehe jetzt dasselbe. –

Antwort

1

Es sieht nicht so aus, als ob ein gemeinsames Wörterbuch existiert. Während Dict auf einem Paar von Array s, eine für die Schlüssel und eine für die Werte basiert, ist es in der Lage, sie in der Größe ändern, wie neue Elemente eingefügt werden. Die Größe eines SharedArray in Worker-Prozessen zu ändern, scheint seltsame Dinge zu bewirken, also kann man sie nicht einfach austauschen.

Wenn Sie mit dem Wachstum Ihres Speichers durchkommen können, könnten Sie ein Paar Schlüssel/Wert SharedArray s mit der richtigen Länge, initialisieren sie in der parallelen Schleife, und kopieren Sie dann die Daten zu Ihrem Dict in den Hauptprozessen. Auf diese Weise können Sie alles ausführen, was Ihre Werte parallel generiert.

Leider ist SharedArray s immer noch problematisch, wenn Ihre Daten kein Bit-Typ sind. Sie können DArray s aus dem DistributedArrays Paket verwenden.

+2

Ein anderes wichtiges Problem ist, dass, abhängig davon, wie die Werte gehashed werden (einige Typen in Julia sind Hashed durch die Verwendung ihrer Adresse, die nicht in verschiedenen Prozessen identisch sein). Es wäre sehr nützlich, in Julia eine gemeinsame Datenstruktur zu haben. –

3

Der folgende Ansatz verwendet @parallel eine Verringerung um das gleiche Ergebnis zu erzielen:

list = [[rand(1:3),4,5] for i=1:10000000]; # define random test `list` 

@everywhere rdc(d::Vector,i::Vector) = rdc(rdc(Dict(),d),i) 
@everywhere rdc(d::Dict,i::Vector) = begin d[i[1]] = 1000; d end 
@everywhere rdc(d::Dict,i::Dict) = merge!(d,i) 

heavy = @parallel (rdc) for item in list 
    item 
end 

heavy wird nun halten:

Dict{Any,Any} with 3 entries: 
    2 => 1000 
    3 => 1000 
    1 => 1000 

Die Idee ist, ein anderes Wörterbuch für jeden Arbeitnehmer zu erzeugen, sie bevölkern und schließe die Wörterbücher schließlich zu einem zusammen. Ich hoffe, dass die Kombination von Wörterbüchern schnell genug ist, um dies sinnvoll zu machen - was vernünftig erscheint.

Um die Idee zu implementieren, definieren wir rdc und verwenden mehrere Versand, um es für drei Zwecke zu dienen: 1) Initialisieren Sie ein neues Dict auf jedem Arbeiter. 2) Verschiebe einen neuen Gegenstand in einen existierenden Dict eines Arbeiters. 3) Kombiniere die Dicts von verschiedenen Arbeitern in der Endstufe @parallel. Die drei Methoden von rdc im obigen Code (in ihrer jeweiligen Reihenfolge) implementieren dies.

Die Notwendigkeit für SharedDict oder SharedArray wird vermieden, da die Mitarbeiter an verschiedenen Objekten arbeiten und die endgültige Kommunikation zwischen den Mitarbeitern in der Implementierung @parallel ausgeblendet wird.