Raspberry Pi - Java GPIO Frequency Benchmarks
Overview
In a previous article we covered Java runtime benchmarks using various JVMs. Typical benchmark testing runs a series of varied task-based tests that attempt a wide array of coverage. While these benchmark tests are great for generalized comparisons, I was curious how fast Java programs could update/write to the GPIO pins. So this article is a very coarse-grained comparison on a single data point ... frequency of GPIO state changes.
Test Control Program
The test program used simply toggles the GPIO state between HI and LOW states as fast as it can by executing in a tight continuous loop. Measurements were made using a digital oscilloscope (DSO) with the probe attached to GPIO pin 1.
Additionally ...
- Each of the Java tests below are based on accessing GPIO using the Pi4J library. (JNI to native WiringPi)
- Each of the measurments below for JVMs are based on this test program:
https://github.com/Pi4J/pi4j/blob/master/pi4j-example/src/main/java/FrequencyGpioExample.java - Each test was executed on the same Raspberry Pi hardware. (512MB / Model B)
- Each test was executed running on the latest Raspbian "Wheezy" Linux distribution. (hard-float ABI)
OpenJDK 7 - ZeroVM
The following (single) snapshot reading was sampled from the test program while running it on the OpenJDK with the ZeroVM. The GPIO pin was able to toggle states at a frequency of approximately 5 kHz.
OpenJDK 7 - JAMVM
The following (single) snapshot reading was sampled from the test program while running it on the OpenJDK with the JamVM. The GPIO pin was able to toggle states at a frequency of approximately 10.75 kHz, a notable improvement over the ZeroVM.
OpenJDK 7 - Avian
I did attempt to run the test program using the Avian VM with OpenJDK; however the test program failed to start. This error message was displayed on screen: "NATIVE (GpioInterrupt) ERROR; GpioInterrupt class not found." It appears there is some issue loading the native JNI library.
Oracle JDK SE 8 Preview for Linux/ARM (early access)
The following (single) snapshot reading was sampled from the same test program while running it using Oracle's JDK SE 8 Preview for Linux/ARM. (Installing Oracle Java SE 8 (with JavaFX) Developer Preview for ARM) The GPIO pin was able to toggle states at a frequency of approximately 153 kHz. The VM really seems to make a difference here.
Native C
For reference, I wanted to also include a native C test program for comparison. The following readings were sampled from a native sample test program that implements the same test logic. Access to the GPIO is accomplished using Gordon's WiringPi library.
The GPIO pin was able to toggle states at a frequency of approximately 7 MHz.
Summary
Below is a summary of the results:
- Java + OpenJDK 7 + ZeroVM = 5 kHz
- Java + OpenJDK 7 + JamVM = 10.75 kHz
- Java + OpenJDK 7 + Avian = Error; untested
- Java + OracleJDK 8 (ea) + HotspotVM = 153 kHz
- Java + OracleJDK 7u10 + HotspotVM = 161 kHz (on soft-float Debian "Wheezy")
- Native C + WiringPi = 7 MHz
If you are using Java and need hi-speed IO changes, then running on the Oracle JVM seems to be the best option at this time. If you need really hi-speed IO, then you may want to think of pushing that work down into a native library. It you require very precise timing, then please keep in mind that Linux is not a real time operating system.
Hopefully this information sheds a little light, albeit on just one key metric, on how the different JVMs perform on the Raspberry Pi.
Here is a great article that performs similar GPIO frequency testing on other languages/configurations:
http://codeandlife.com/2012/07/03/benchmarking-raspberry-pi-gpio-speed/
Oracle JDK SE 7u10 for Linux/ARM (soft-float)
Per request, I have added the measurements for Oracle JDK 7u10. One difference here is that I used Debian "Wheezy" and not Raspbian since this version of the JDK is does not support hard-float ABI. This test The GPIO pin was able to toggle states at a frequency between ~150 to ~162 kHz. So this was very close to the same results as Oracle's JSK 8 (ea).