0

I have a float[][] of pixels of an image, I will perform an operation on each pixel of this image. My current implementation is as follows:

float[][] pixels = image.pixels;

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

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

        //perform operation on pixel

    }

}

This implementation is very slow and I would like to speed it up by parallelising the for loops, how would I go about doing this?

gasdhj
  • 17
  • 4
  • The best way would be to turn those pixels into streams using JDK8. You might find that the memory (1MB per thread) and overhead of parallelizing per pixel will actually slow things down because of context switching. One thread per core is likely to be the best you can do. – duffymo Nov 08 '17 at 12:23

3 Answers3

0

You have 2 main options.
1) Would be using streams (Java8 +) where depending on what you are doing in your operations, the parallelism is mostly done for you, as you can make use of a parallelstream (NB: for small datasets, there is an overhead associated with it & sequential streams may in fact deliver comparable performance).

2)Alternatively, you can do the parallelism yourself by using threads, and delegate subsections of the datasets to different threads, if you are doing more lightweight tasks, you can use ForkJoin threads or else just normal threads.

Luvy
  • 96
  • 2
0

You can use Java 8. Streams use parallel execution operations which is faster than sequential execution with only a single thread. So you could try the below code in order to perform any operation with better performance than a nested for loop.

    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

Change the order of 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 these type of operations, a large percentage of time goes into memory access. If you iterate the outer array in the inner loop, then memory access is not sequential, causing a lot of cache misses. See e.g. Why does the order of the loops affect performance when iterating over a 2D array? for more details.

fishinear
  • 6,101
  • 3
  • 36
  • 84
  • Your link is for C. For Java you don't always know what hardware or OS the code will run on. I did a simple 2D "fill in the arrays" using both iterations and there was no difference in timing. – edharned Nov 09 '17 at 20:08