GCJ, a quest for speed.

What is Alien Flux?

At the moment I don’t think GCJ would be faster than Jet as GCJ is still in it’s early stages.

But then you have the ability to turn off bounds checking with GCJ, which is the bit making my fingers itch!

Of course I don’t actually have Jet to make a comparision, which sounds like a job for you Cas :wink:

Neither would it meet you magic 5 Meg file size at the moment, as even simple applications are compiling to around 4 meg. Although interestingly the files are initially 1/3 smaller, then mysteriously bump up a meg or so.

Those error messages look quite confusing, I haven’t encountered them at all (or at least don’t remember).

If this is a large project try starting with a small section and get that running - then enlarge.

It might be just that it is not finding the correct files, although GCJ does have some quirks in its language parser.
things like this:

import java.awt.image.*;

did not work for me, I had to make my libraries explicit

import java.awt.image.MemoryImageSource;
import java.awt.blahblahblah;

(Note: not that the awt exists in GCJ V3.2, I just used it as an example!)


Woz.

Jet seems to be removing bounds checks where it’s safe to do so by using loop versioning and other tricks. At any rate, I’ve gotten the entire Alien Flux distribution down to under 5Mb - an exe and 2 dlls with Wise to install it - what’s amazing about this is that the bytecode distribution is only a megabyte smaller!

Cas :slight_smile:

Hi all,

just thought I’d inform you all that a slightly newer version of the GCC has been release.

I say slightly because its Version 3.2.3 which is a bug fix for V3.2.2.

try: http://gcc.gnu.org/gcc-3.2/changes.html#3.2.3
It does contain a couple of bug fixes for GCJ, but I don’t think it will effect any one here (anyone running irix???!).
Bug fixes:

9652: libgcj build fails on irix6.5.1[78]

10144: gas on solaris complains about bad .stabs lines for java, native as unaffected.

I have no idea why Version 3.3 has not been released yet, althought the preview is still available (can be found in a post above) and works a just fine.

All the best.

Woz.

P.S.
As a side note I noticed Out-of-the-Box 2.0 has been released, which may/may not interested people:
http://www.ejbsolutions.com/new-projects.html

Hi,
I’ve just started playing with GCJ, and running up to the import problem, does anyone know of a tool to change the imports automaticly?

In a unix enviroment I’d use sed.
On Win32 I don’t know but I’d start looking at the filter ability of Ant’s copy task and see if I can get it to search/replace what I want.

OK, supposed to be revising for my exams, so obviously been playing with gcj all day!

I’ve now got a compiled helloworld down to just under 1/2 meg by stripping out all symbols and running through upx. This is supposedly the full runtime as well, so looking good :slight_smile:

nio is partly there, but not direct buffers yet, so still no lwjgl support. Shouldnt be long though as the stubs are there, just needs an implementation.

I’m all set up to compile the runtime as well now, so I’m going to try stripping out all the stuff I dont need from the library and see if I can get the file size down even more…

[quote]In a unix enviroment I’d use sed.
[/quote]
Woo, writing sed files, the fun…

Anyway worked it out, compile it with javac :wink:

GCC 3.3 is released,

containing quite a few changes to GCJ, although not really enough to be useful to most of you. So we’ll have to wait for version 3.4 - which was expected anyway.

New GCJ features:
* The java.sql and javax.sql packages now implement the JDBC 3.0 (JDK 1.4) API.
* The JDK 1.4 assert facility has been implemented.
* The bytecode interpreter is now direct threaded and thus faster.

But contains plenty of bug fixes, there is to many to list but can be found here http://gcc.gnu.org/gcc-3.3/changes.html.

The www.mingw.org version is not yet ready (judging from source forge), but should be soon-ish…


Just to clear up what Jacko is saying:

Here is the most exciting “hello world” program, in java:


public class hello 
{ 
  public static void main(String[] args) 
  { 
    System.out.println("Hello World"); 
  } 
}

Compiling this file using GCJ to produce an .exe file with:

gcj --main=hello -o hello hello.java

Produces a file that is 2,606,061 bytes in size or 2.6Meg !

To remove symbols from the .exe file, compile instead with:

gcj --main=hello -o hello hello.java -Wl,--strip-all 

Be careful with the syntax that is an L in the -Wl, it’s also case sensative.
This will produce a file size of 1,816,064 bytes or 1.8 meg.

Using a well known .exe file compressor UPX (Ultimate Packer for eXecutables) by Markus Franz Xaver Johannes Oberhumer (that is just one person) and László Molnár.

This can be located on the UPX web site http://upx.sourceforge.net/.

Using the recommanded switches for best compression :

upx --best --crp-ms=999999 --nrv2d -o hellod.exe hello.exe

Produces a file size of 495,104 bytes or ~483K.

A great improvement on the 2.6 Meg file initially created.

All the best,

Woz.

P.S.
Jacko get back to the revision! You’ll only regret it if you mess up your exams!
Best of luck with them too!

3.3 is really better as far I tested it (more ocmplete)

but it miss Direct Buffer which screw LWJGL

JNI works
I compiled a LWJGL expample, run it, the window opened but got a message : direct buffer non implemented :(.
elias said it’s for next gcj release

for now it’s going better every release,
good to test often

just to let people know whats going on with gcj…

On www.thisiscool.com there isa development version of gcj 3.4 with … support for direct byte buffers!!

gotta go to a lecture now, but I’ll try this later to see how well it works.

Heh, HelloWorld is now 4.6MB. :o

Other than some really trivial things, I couldn’t get anything to compile and run correctly. Some test programs required some hacks to get it to compile.
For example for doing a quick and dirty new Date().toString(), I finally had to add 2 static references to gnu.java.locale.Calendar.class and gnu.java.locale.LocaleInformation.class in my source, which is a bit weird ???. The little test program BTW is a simple socket that returns the time, but the GCJ version compiles and runs (after inserting the extra lines of dummy code), but behaves differently (I couldn’t test the response from the socket using a browser where I can with the java version).

If I can’t even get these miserable 50 lines of code running, I won’t even bother with compiling a LWJGL program.

Using GCJ is certainly no walk in the field :-[.

I’m not giving up just yet, but so far no result at all.

Thats pretty good figuring a simple HelloWorld in regular java is over 30MB is size.

Now some of you are thinking that I must be crazy BUT you may be forgetting that a GCJ compiled program includes a Java runtime. So, add the size of your JRE with any java app you write to figure the size in comparison.

There is a DLL you can link your GCJ programs to for Windows that takes out the java runtime fat (Google for libgcj.dll). Thats nice if you are planning on having multiple GCJ apps on the same system.

Also, check out UPX (upx.sf.net). Use it to deflate GCJ apps.

upx --best HelloWorld.exe

Yes, this is a known issue. But its the only oddity I have ever seen. What other problems are you having?

Post your code. I curious to whats going wrong.

Here’s my test:


import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * TServer.java
 */
public class TServer {

        private static final Class class1 = gnu.java.locale.Calendar.class;
        private static final Class class2 = gnu.java.locale.LocaleInformation.class;

        int port;

        public TServer(int port) {
                this.port = port;
        }

        public void run() {
        boolean waiting = true;

        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(port);
        } catch (IOException e) {
            System.err.println("Could not listen on port: " + port);
            System.exit(1);
        }

        while (waiting) {
                Socket clientSocket = null;
                System.out.println("Waiting for request");
                try {
                    clientSocket = serverSocket.accept();
                } catch (IOException e) {
                    System.err.println("Accept failed.");
                }

                PrintWriter out = null;
                        try {
                                out = new PrintWriter(clientSocket.getOutputStream(), true);
                        } catch (IOException e) {
                                System.err.println("Error getting PrintWriter:" + e);
                        }

                out.println(new Date().toString());
                out.close();
                try {
                                clientSocket.close();
                        } catch (IOException e) {
                        }
        }
        try {
                        serverSocket.close();
                } catch (IOException e) {
                }
        }

    public static void main(String[] args) throws IOException {

        if (args.length != 1) {
                System.out.println("Usage: TServer [port]");
                System.exit(1);
        }

        TServer t = new TServer(Integer.parseInt(args[0]));
        t.run();


    }
}

[quote]Quote:
Heh, HelloWorld is now 4.6MB.

Thats pretty good figuring a simple HelloWorld in regular java is over 30MB is size.

Now some of you are thinking that I must be crazy BUT you may be forgetting that a GCJ compiled program includes a Java runtime. So, add the size of your JRE with any java app you write to figure the size in comparison.
[/quote]
Yes, you’re absolutely right but downloading a runtime with every GCJ app makes a one time download of a more functional JRE look more attractive still.

I’m still interested in getting GCJ to compile my LWJGL stuff, but it will be of very limited use: To make a one time download of the game or game demo a bit smaller and easier.
I did some more tests and there seems to be no speed gain with GCJ. For example the ‘ArrayTest’ code from the http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=Tuning;action=display;num=1065650709 thread is a tiny bit slower in GCJ compiled form than running the java code in the 1.4.1 client VM.

Erik

I didn’t have that much trouble getting hello world down to < 500K.

You’ve just got to use lots of GCC switches!

Page 2 of this topic has the correct switches listed to get < 500K.

They are supposed to be doing something about the size in GCJ V3.4 but how much difference it will make is another matter - bearing in mind that you have to provide the functionality of the JVM and the compiled code in order for it to execute properly.

Jacko points out that a preview of 3.4 is available from the http://www.thisiscool.com/gcc_mingw.htm but whether that includes the size modifier I don’t know. Neither have I been able to try it yet due to an annoying combination of zero time and a hard drive failure.

As to the array speed test, this does not surprise me but did you try it with the Array Bound Checking switched off in GCJ?

The simple fact is that the array fill is compiling into exactly what it has been asked to be. Which is not particully optimal for execution speed on the cpu and memory subsystem. This is a problem of it looking fast to humans, but not being fast for a cpu. For example I would not use that code in C (other than for easy of use that is [read laziness :D]).

There has been a lot of success with GCJ and SWT, for example Eclipse has been successfully compile, which is hardly a small product.

Hopefully using GCJ will become easier.


Woz.

Yes, I’m aware of the GCC switches and upx and all to shrink the executable. I’m not too worried about all that. The reason I mentioned the straight helloworld example is now 4.6MB, was just an observation that the helloworld.exe went from 2.6 to 4.6MB as of GCJ 3.4.

[quote] but did you try it with the Array Bound Checking switched off in GCJ?
[/quote]
blush er I’m afraid not until just now:
The GCJ version is not ~13% faster than the client VM version and still 5% faster than the server VM version (wasn’t the server VM supposed to eliminate bounds checks too?).
That’s very good indeed. :slight_smile: