1

I'm currently doing some research in Genetic Programming, and I don't have access to multiple computers (yet) such that I can perform aggregate computations. Right now, the research only takes about 1.5hrs on my home desktop so it is not unbearable, but as the analysis becomes more advanced I expect a significant increase in the size of the data.

What are some ways we can optimize Java's use of the processor under these conditions?

James
  • 903
  • 7
  • 22
  • 7
    Optimize the critical path in your (unposted) code first. Then, look for better algorithms. – Elliott Frisch Nov 16 '15 at 22:58
  • 4
    Profile your code to analyze where it spends most of its time. This can guide you on what parts to try to optimize. – John Bollinger Nov 16 '15 at 22:59
  • 1
    Profile memory use and GC activity, too. It is sometimes the case that just increasing the VM's heap size can be a big win. – John Bollinger Nov 16 '15 at 23:00
  • @ElliottFrisch Unfortunately the code is far too large to be posted. I'm using a fairly extensive GP library, which implements some of the best known algorithms in the field. – James Nov 16 '15 at 23:02
  • @JohnBollinger I'm running a profiler as we speak actually :) was hoping to see if their are any tricks in Java that are good for this scenario. – James Nov 16 '15 at 23:03
  • If you are running single-threaded code on a multi-core CPU, then you may be able to reduce elapsed time by using multiple concurrent threads. This is *distinctly* non-trivial, however. – John Bollinger Nov 16 '15 at 23:03
  • 1
    See also [Amdahl's law](https://en.wikipedia.org/wiki/Amdahl's_law). – Elliott Frisch Nov 16 '15 at 23:04
  • @JohnBollinger I'm looking heavily into the process of threading portions of the computation. Fortunately it seems now that a large percentage of the work can be run in parallel. – James Nov 16 '15 at 23:08
  • Make sure you're looking at executors in preference to manual thread management. The Java 6 concurrency features sound like a good match for genetic evaluation. – chrylis -cautiouslyoptimistic- Nov 16 '15 at 23:19
  • Java Visual VM https://visualvm.java.net/ for performance analysis, to find out how your code uses memory, processor, network, etc resources. – Raf Nov 16 '15 at 23:33
  • @James if you have Java 8 you may find `parallelStream()` is easier to work with than using ExecutorService directly. If you are not using Java 8, I suggest you upgrade and that might speed up you code a little. – Peter Lawrey Nov 16 '15 at 23:39
  • 1
    I also suggest you use Flight Recorder instead of VisualVM. It is more accurate and it's CPU profiling tends to better (as it doesn't use instrumentation or JMX as much) – Peter Lawrey Nov 16 '15 at 23:41
  • what kind of problem do you solve? regression or classification? if so, how many data has your training set? – Mihai Oltean Nov 17 '15 at 13:44

1 Answers1

0

Since you're working with genetic programming, you spend lot of operations doing one (or many) of the following :

  • Computing next generation (crossover, mutation)
  • Fitness function computing
  • Garbage collecting if your population is very large

To determine the hot spots of your code, use JVisualVM, the sampling pane will be enough for your use case.

From my experience, I would say there are two main probable hotspots:

  • Slow crossover and memory exhaustion: this is related to uncompact individual representation. You can gain significant performance by reducing individual's memory footprint. Try to put it in a primitive array whenever possible.
  • Slow fitness : This is more difficult, you may want to reduce the number of program evaluation, or go for more significant examples.

If you're working with a fixed-size population, you may consider working off-heap, but this may significantly complexify your program.

I don't know if you are using a framework like JGAP, but this latter is deadly slow, too many encapsulations and large call stacks. It is very good for proof of concepts, but when things get intensive, you have to do it yourself.

EDIT: reading the comments, I see that your code is not parallelized, you must absolutely start with that. This is trivial for GP, just run the fitness in parallel, then the next generation computation in parallel.

Julien
  • 1,302
  • 10
  • 23