In earlier testing I found that the Asus Tinker Board utterly sucked as a Java platform. As a ‘C’ programmer that usually wouldn’t bother me, but in this case I was trying it out as a Minecraft server, something which should be within the board's capabilities. If you know the workings of Java you can skip the next bit, but some background could help here.
Java programs are intended to be run on a Java Virtual Machine. Such machines don’t really exist, hence the “virtual” bit in the name. There were some attempts at building a Java CPU that could run these programs directly, but they were ultimately a bit pointless so all fizzled out. So we ended up with two main ways of running Java programs: “interpreted” and “translated”.
In the interpreted case, the JVM is just another program, one which looks to see what the next instruction is in the java program and does what it asks to be done. So a program is run by a program, which involves lots of looking stuff up and is generally a bit slow.
For a translated program, we convert the program from the Java instruction set into whatever the CPU is we are using, in this case JVM to ARM instructions. Modern Android devices do this with the ANT runtime, you load an app and it gets translated on download so it can run nice and fast.
Now usually Java programs sort of go somewhere in the middle with what is called a “hotspot” compiler. We start off with the program being interpreted because that doesn’t involve waiting for a translation to happen, and if the JVM finds the same bit of code is run over and over then it translates it so that the CPU can run it directly next time. So interpret the bits that don’t matter, and translate the bits that do, and that works rather well.
Unfortunately Asus ship a Debian install where the java system is “OpenJDK”. On a PC that’s a fine choice that uses hotspot, but on an ARM device that gets you a pretty slow interpreter.
After looking around it seemed that the easiest way to get a faster Java was to use the Oracle JVM instead of OpenJDK. At this point I should come clean, I hacked the Oracle JVM onto the Tinker Board rather than find a good way to install it. I didn’t want to spend ages getting a nice clean package built only to find that I still had a sucky Java experience and all that time was wasted, so I cheated.
It is possible to download an ARM JVM directly from Oracle, but it comes as a .tar.gz file not a Debian package. At that point, it needs extracting to the right place, fixing any privilege problems and getting the /etc/alternatives system to know about it so that it runs. I am more of a Red Hat man myself, so figured a shortcut was in order. The Raspberry Pi has a package, how about I crowbar that onto the Tinker.
I can’t recommend this, it will probably trash your install, but I will give the steps I took in case someone can improve on it. I was intending to wipe the SD card after anyway so personally I wasn’t risking anything.
First I did the stupidly dangerous move of telling the Tinker it should use the Raspian package repositories. To do this I edited the /etc/apt/sources.list file and added the line at the end:
http://archive.raspberrypi.org/debian/ jessie main ui staging
and that is something that absolutely has to be undone straight after this is finished because updating from that repo would almost certainly trash your install. Now to read in the repo information. To allow for the fact that the tinker has no idea what it is reading we must turn all the safeties off:
$ sudo apt-get --allow-unauthenticated update
That done, time to actually grab the package:
$ sudo apt-get install oracle-java8-jdk
then I went back to /etc/apt/sources.list and deleted that extra line. For good measure I also did a:
$ sudo apt-get clean
which hopefully got rid of all memory of Raspbian. That got me the package installed, but java still points to the old interpreter. One last command needed:
$ sudo update-alternatives --config java
$ java -version
Picked up JAVA_TOOL_OPTIONS: -Dgnu.io.rxtx.SerialPorts=/dev/tty96B0
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) Client VM (build 25.65-b01, mixed mode)
At last, Oracle Hotspot is the system JVM of choice.
As in my first look at Tinker, I am measuring two Java related things: how long it takes to compile up a new copy of Spigot server and how long it takes the resulting Minecraft server to start. That isn't ideal, but there don't seem to be any proper Minecraft benchmarks yet. You can measure ticks per second, but that shows how badly a server is failing rather than how well it is running!
The compile script is pretty simple, it deletes everything in the build directory, does a “wget” of the latest Spigot build tool and then runs it. Result is measured with using the Ruby time class, and the wall clock “real” time is recorded.
The resulting binary is then used for the second test. Again, the work directory is cleaned out with an rm -rf, and then a couple of configuration files are created. A server.properties file is set with a fixed seed to make runs more consistant, and an eula.txt is created to accept Mojang's conditions.
The server is run with the command:
java -Xmx1024M -Xms512M -jar spigot-1.11.2.jar
When the server is run a new world is created, and when that is finished a line is spat out on the console which says how long Spigot took to start, which is what I report here.
Tests are run three times, best number reported (compile can be hurt by network problems doing git clones etc).
First of all how does it compare against the OpenJDK interpreter.
Compile time has improved by a factor of 28, but start-up gives the hotspot translator something to get its teeth into so performance improves by a factor of 64. That is quite hard to wrap your head around, every minute that the interpreter needs takes just under one second with hotspot. That’s a huge difference, but is it enough.
It takes the Pi3 some 75% more time than the Tinker Board to compile the server, and start-up time is closer to the Atom board.
Well it still isn’t screaming fast, but it is looking kind of usable. To compare against something way way bigger, an FX8350 CPU with 16GB of ram can do the compile in 145 seconds, and starts up in 21.2 which is enough improvement that you would be able to feel the difference in a server, but could easily be considered overkill.
There are certainly limits. With a server up and running it seemed only right to fire up a client and have a play. I left the server with the default draw depth and in Survival mode on my own it seemed very playable.
Switching to Creative didn't go so well. Things were fine until I started to fly and headed off into the distance. The Tinker was drawing over an amp so working fairly hard, and it couldn't keep up with serving new chunks if you just flew in a straight line.
Looking at the the output from "top", the CPU was never going over 70% so I figured the machine must be I/O bound. A quick ext3 format of a fast USB stick later and the server was moved onto that and restarted. Now the CPU would hit 120% when flying, and the server was almost keeping up. I imagine two users flying in opposite directions would flatten it still though. Sadly I didn't have a USB connected SSD handy to try even faster storage.
It might be possible to tune some of this out, I am still running the usual 1GB of ram friendly java settings and "top" says there is half a gig free. It might also be an idea to turn down the server's draw distance to limit what the client can ask for.
However, in survival mode it seemed OK. There was only one real glitch that I saw, I stumbled across this village and the villagers were sprinting about rather fast. None of the animals seemed to do that, just villagers!
So overall, if you want to get a Tinker Board anyway then it just about scrapes by as a survival server. I wouldn't recommend buying one for the job though. Perhaps we need to wait for a cheap A72 based board before we get something really up to the task.