2017-11-08 6 views
0

Ich habe ein float [] [] von Pixeln eines Bildes, ich werde eine Operation für jedes Pixel dieses Bildes durchführen. Meine aktuelle Implementierung ist wie folgt:Wie parallelisiert man ein 2D-Array in Java?

float[][] pixels = image.pixels; 

for(x = 0; x < pixels[0].length; x++) { 

    for(y = 0; y < pixels.length; y++) { 

     //perform operation on pixel 

    } 

} 

Diese Implementierung ist sehr langsam, und ich möchte es durch Parallelisierung der for-Schleifen beschleunigen, wie würde ich mich über das tun dies?

+0

Der beste Weg wäre, diese Pixel mit JDK8 in Streams zu verwandeln. Sie werden feststellen, dass der Arbeitsspeicher (1 MB pro Thread) und der Overhead der Parallelisierung pro Pixel die Conversions verlangsamen. Ein Thread pro Kern ist wahrscheinlich der beste, den Sie tun können. – duffymo

Antwort

0

Sie haben 2 Hauptoptionen.
1) Wäre Streams (Java8 +) wo je nachdem, was Sie in Ihren Operationen tun, die Parallelität ist für Sie getan, wie Sie einen Parallelstream verwenden können (NB: für kleine Datensätze gibt es einen Overhead im Zusammenhang damit & sequentiellen Streams kann tatsächlich eine vergleichbare Leistung liefern).

2) Alternativ können Sie die Parallelität selbst tun, indem Sie Threads verwenden und Unterabschnitte der Datensätze an verschiedene Threads delegieren. Wenn Sie leichtere Aufgaben ausführen, können Sie ForkJoin-Threads oder nur normale Threads verwenden.

0

Sie können Java 8 verwenden. Streams verwenden parallele Ausführungsoperationen, die schneller sind als die sequenzielle Ausführung mit nur einem einzigen Thread. Sie können also den folgenden Code verwenden, um eine Operation mit einer besseren Leistung auszuführen als eine verschachtelte for-Schleife.

Float[][] pixels = new Float[][]{{1f,2f,3f},{1f,2f,3f}}; 
    Float[][] pixelArray = Arrays.stream(pixels) 
          .map(arr -> Stream.of(arr).chooseWhatYouWantToDo()) 
          .toArray(Float[][]::new); 
0

Ändern der Reihenfolge der Iteration:

float[][] pixels = image.pixels; 

for(y = 0; y < pixels.length; y++) { 

    for(x = 0; x < pixels[y].length; x++) { 

     //perform operation on pixel 

    } 
} 

In dieser Art von Operationen, ein großer Prozentsatz der Zeit geht in Speicherzugriff. Wenn Sie das äußere Array in der inneren Schleife iterieren, ist der Speicherzugriff nicht sequenziell, was zu einer Menge Cache-Misses führt. Siehe z.B. Why does the order of the loops affect performance when iterating over a 2D array? für weitere Details.

+0

Ihr Link ist für C. Für Java wissen Sie nicht immer, auf welcher Hardware oder welchem ​​Betriebssystem der Code ausgeführt wird. Ich machte eine einfache 2D "Füllen Sie die Arrays" mit beiden Iterationen und es gab keinen Unterschied im Timing. – edharned

Verwandte Themen