New VM performance improvements

I fear that Structs are a hot potato. Lots of people have all sorts of different solutions to the same problem, and my proposal doesn’t make most of them happy. I just want fast memory mapped interfaces between ByteBuffers and Java Objects. Mostly everybody else wants stuff like LWOs for maths and such. The issue is clouded because people like to think there is some overlap and that if there isn’t overlap then there should be or it’ll make everyone confused. IMHO my Structs RFE has nothing to do with LWOs and should be kept completely separate.

But that, in a nutshell, is why I think no-one has replied yet. Not even Azeem…

Cas :slight_smile:

Structs would be cool SOMETIMES, but I think they are as useless as generics. A cast more or less is nothing compared with the added complexity of the java-language :frowning:

However I do not want to start another flame so I will ask something completly different :wink:

What really would fascenate me would be something called like “hotspot-performance guide” where some tipps are given to the developers with different toppics.
This should in general not concentrate onto API-stuff, it should focus much more on howto write java that can be generated to efficient bytecode.
Sections like FP-calculations (when SSE will be used…), int-calculations, loops, switch-statements and so on.

[quote]I just want fast memory mapped interfaces between ByteBuffers and Java Objects.
[/quote]
Your original proposal includes a language change and that is what most people see when they look at that RFE. This opened the can of worms relating to light weight objects, and it is hard to put the lid back on.

Unfortunately I can’t edit the damned thing :confused:

Cas :slight_smile:

I’m a peon here, nobody will listen to what I say. I tried to talk to Graham about structs and he said “Sorry too specialized can’t do it”. Basically I doubt this will happen, unless several large corporations get together and ask for ir through the JCP.

[quote]I’m a peon here, nobody will listen to what I say. I tried to talk to Graham about structs and he said “Sorry too specialized can’t do it”. Basically I doubt this will happen, unless several large corporations get together and ask for ir through the JCP.
[/quote]
How difficult do you think it would be to implement the change? If some of us got together and modded the 1.5 JVM to support structs, would there be a good chance that you could get those changes accepted into a new release? (Let’s assume no language changes). We could provide some sample benchmarks that would demonstrate the performance improvements.

The only reason that this feature appears “too specialized”, is because people have generally avoided using Java for high-performance tasks. Now that more people are attempting to use Java for those kinds of applications, they’re bumping up against real problems.

God bless,
-Toby Reyelts

Darn, someone should move the structs thread over at Off Topic into Performance Tuning.

Anyway, I think we need someone to write an article detailing all the different reasons different people propose structs, and compare the proposed solutions.

The article might conclude structs won’t be the best solution to some of these performance problems, and escape analysis will do there. The article will explain to those affected why escape analysis is better in these cases and why structs will be better in other cases.

Then it will go on to propose a struct design that solves all problems not solved by escape analysis and perhaps by some other means.

This will hopefully unite developers into supporting this common design (well, I did say hopefully) and form the basis of a serious community backed design to present to Sun.

Anyone up for it? Write the article I mean.

Seb

Forgetting for a moment various alternative uses of structs, what is the minimum needed to get reasonable performance for IO use?


void putStruct(ByteBuffer b, int offset, MyData z) {
b.putShort(offset, z.a);
b.putInt(offset+2, z.b);
b.putInt(offset+6, z.c);
}

Given code like this, would it not suffice to optimise the bounds checks and assignments involved in those calls. Pseudo code like this


if (b.isNativeOrdering && b.limit >= offset+10) {
   ((short*)(b.bytes+offset)) = z.a;
   ((int*)(b.bytes+offset+2)) = z.b;
   ((int*)(b.bytes+offset+6)) = z.c;
}
else {
   // do it the hard way ...
}

Then if this code appeared in a loop just do the usual strength reduction and unrolling as well.

I’m sure something along these lines could be achieved using reflection, the new metadata tags in 1.5, a modified classloader and a dynamic bytecode generator, using the sun.misc.Unsafe class…

Cas :slight_smile:

[quote]Darn, someone should move the structs thread over at Off Topic into Performance Tuning.

Anyway, I think we need someone to write an article detailing all the different reasons different people propose structs, and compare the proposed solutions.
[/quote]
To be complete it should also research and present clearly the arguments given for why structs haven’t been done to date. I’m no expert but I believe their are some serious VM complications and perhapse some security problems that this would introduce due to java’s late binding.

Hi,

I started a thread over at JavaLobby about the different suggestions on how to implement structs.

Why JavaLobby? Well it’s my job, I’m an editor there ;), but most importantly because I think it a great location to get input from the whole community on this particular matter that goes beyond the development of games so that all ideas are put on the table and other people are exposed to the possibility.

Perhaps get a serious and complete proposal going.

Seb

Can’t reply to it :frowning:
“You are not authorized to create a new user account.”

Cas :slight_smile:

Hi Cas,

In Rick’s own words: “we have been having a mysterious problem with connections bombing […] should be fine now”.

Give it another try and let me know how it goes. Thanks,

Seb

Works now.

Cas :slight_smile:

I threw my 2 cents worth into the discussion with this response. Sorry for not cross-posting, but I’m feeling lazy. ;D

Edit: Ah, hell. I guess I’m not that lazy. Here it is:

You’re looking for something like this?


//File: Test.struct
//Purpose: Demonstrates the Struct class type

package com.mypackage;

public struct TestStruct output Bean order Big
{
    byte b;
    short s;
    int i;
    long l;
    
    float f;
    double d;
    
    double[3] vertex;
    int[i] texture;
}

Which then outputs a java file like this:


package com.mypackage;

import java.nio.*;

public class TestStruct
{
    private ByteBuffer buffer;
    private boolean hasArray;

    private int[] positions = new int[8];

    public TestStruct(ByteBuffer buffer)
    {
        ByteBuffer temp;

        int position = 0;

        this.buffer = buffer;
        this.hasArray = buffer.hasArray();
        this.positions[0] = position;
        buffer.position(buffer.position()+1);
        position += 1;

        this.positions[1] = position;
        buffer.position(buffer.position()+2);
        position += 2;

        this.positions[2] = position;
        buffer.position(buffer.position()+4);
        position += 4;

        this.positions[3] = position;
        buffer.position(buffer.position()+8);
        position += 8;

        this.positions[4] = position;
        buffer.position(buffer.position()+4);
        position += 4;

        this.positions[5] = position;
        buffer.position(buffer.position()+8);
        position += 8;

        this.positions[6] = position;
        temp = buffer.slice();
        temp.limit(3);
        this.vertex = temp.asDoubleBuffer().array();
        position += 3 * 8;

        this.positions[7] = position;
        temp = buffer.slice();
        temp.limit(getI() * 4);
        this.texture = temp.asIntBuffer().array();
        position += (int)getI() * 4;

    }

    public byte getB()
    {
        return buffer.getByte(positions[0]);
    }

    public void setB(byte b)
    {
        return buffer.setByte(positions[0], b);
    }

    public short getS()
    {
        return buffer.getShort(positions[1]);
    }

    public void setS(short s)
    {
        buffer.setShort(positions[1], s);
    }

    //More getters and setters here
}

Here’s the “Struct” format:


package [packagename];

public struct [ClassName] [output Bean|Struct] [order Little|Big]
{
    [primitive] [name];
}

Bean vs. Struct was an alternate method of accessing the data I was working on. Bean is the default. Order controls the little or big endianess of the ByteBuffer. To convert the struct from C to Java, you can simply wrap the structure in a ByteBuffer and pass it to the constructor of your Java “Struct”. The current code requires that the buffer positions be predictable, although I was spending some time working out how they could be make dynamic.

I was working on this in response to Caspian Prince’s desire for a Struct feature. The way I see it, there’s no need to change the Java language when a preprocessor can convert the structures just fine. I stopped working on the project when I realized that J.A.D.E. already had a similar structure concept.

If anyone wants the code I’ve done, I could probably send it to you. Just shoot me an email. :slight_smile:

The most significant problem here is that you are a) still referencing individual fields via getters and setters and not directly in-situ and b) still having to do individual bounds checks on each field access.

In order to do something like vec3f.x += 1.0f; your idea would require a bounds check, a read, an add, a bounds check, and a write. If you subsequently do lots and lots of tweaks on the same struct you’ll be doing lots and lots of bounds checks. They only need to be checked once, when the struct is placed in position in the buffer.

Cas :slight_smile:

Indeed. The (as of yet undeveloped) Struct version of the class was intended to sovle that by producing a class with public members that could be directly modified. The members could then be copied back into the ByteBuffer on a “commit()” or “getByteBuffer()” call. It wouldn’t eliminate the issue, but it would reduce it. :slight_smile:

[quote]The way I see it, there’s no need to change the Java language when a preprocessor can convert the structures just fine.
[/quote]
Umm… ok. So you didn’t change the Java language, but you invented a new language which targets Java. Your new language only has half-assed language support through the existing Java tools (e.g. editors and debuggers). In general, code generation suffers several drawbacks, and it’s why bytecode rewriting has become so popular.

Given all that, the simplest and most effective change you could make to your application is to change it to use annotations and APT. You’d still be generating code, but at least it would mitigate some of the drawbacks of your current solution.

God bless,
-Toby Reyelts

made some clarifications

Allright, I just posted at JL a summary of most things said so far including this thread.

However I’m not cross-posting as my intention is to have you reply over there so that the broader community gets to read and participate, not just us guys over at the gaming forums. Thanks,

Seb

Link didnt work for me, try this:

http://www.javalobby.org/forums/thread.jspa?threadID=15807&messageID=91818608#91818608