What good is java.nio for?

Okat this is all AIUI, i coudl be wrong BUT…

It depends on the OS. Most OS’s have internal buffers. If you are effectively reading and writing the data without movign it out of rthe kernel then it doesn ot need to be copied. So for instance, if all yo uare doing is getting the memory mapped page and pushing it out a socket, no a sensible OS is not going to make a copy.

If you need to operate on it though then its likely goign to need to transition the data from kernel space to user space and that may well requrie a copy there. Then if you are going to do any kidn of operatiosn on the data from Java, your goign to have to pull it into the Java heap.

Read/write you can do in the Native Byte Buffer, and one would hope that it moves directly from one to the other, but unelss al yo uare doing is dumping raw pre-calculated bist into the video memory, for instance, or out a socket in the case of a HTTP server, then its likely your gonna have to brign it over to the Java side of things.

Edit: Just so it doesnt get lost ina side discussion, because it is by far trhe ,most important poitn in this thread, none of this chnages the afct tha the original poster is beign very premature in trying to optimise his code before hes even written a line and is just going to hurt himself this way.

Yes but you guys didn’t answered the mans orginal question. What is nio good for ? ;D

Can you give a specific example where you have used nio in your own programs with a noticiable (benchmarkable) gain ?

If i remenber correctly that Agency9 3d api uses nio to store matrix and vector data. I don’t know how this helps but im sure they would have tested and noticed an improvement.

Specifically: I use NIO direct byte buffers exclusively to pass data to OpenGL, which is basically one of its main reasons for existence, and why LWJGL only allows you to use NIO direct byte buffers and not arrays.

Cas :slight_smile:

So have you guys done any benchmarks comparing the results of using the two methods ? How many times does nio improves performance over java arrays ?

[quote]So have you guys done any benchmarks comparing the results of using the two methods ? How many times does nio improves performance over java arrays ?
[/quote]
NIO buffers do things that were IMPOSSIBLE in previous versions of java. It’s not a case of asking “which is faster, buffer or array?” but of “do I want hardware acceleration…or not?” or (in the case of networking) “do I want DMA…or not?”.

On top of that, the mere existence of native-memory buffers allows you to do a LOT of detailed memory management functions (very broad area covering things listed above plus others not mentioned in this thread) that, again, were simply impossilbe beforehand. This opens up new algorithms as options that may be fundamentally faster than previous algorithms people were using.

A concrete example of what Blah^3 says: using the NV_vertex_array2 extension one allocates large buffers of AGP RAM to write vertex data directly to. You cannot allocate Java arrays at arbitrary points in memory.

Same goes for VBOs.

Cas :slight_smile:

[quote]Yes but you guys didn’t answered the mans orginal question. What is nio good for ? ;D
[/quote]
um yes we did. Its a set of tools to give you capabilities not found
in other Java APis. We listed the tools.

How much they benefit you depends on how well you udnerstand the tools and can use them.

If, for instance, you dont understand why one thread per socket is a scaling problem in large servers then non-blocking NIO sockets won’t make any sense to you at all. If you do, then their utility should be obvious.

Nio is not “magic pixie dust” you sprinkle on your app to suddenly make it faster.

As IBM says “there is no magic pixie dust.”

[quote]So have you guys done any benchmarks comparing the results of using the two methods ? How many times does nio improves performance over java arrays ?
[/quote]
Um… did yo umiss a post? To quote myself…

I see. So we have the possibility to access special memory areas. Thats cool. But won’t that make you have diff sets of classes to handle diff hardware ?

[quote]I see. So we have the possibility to access special memory areas. Thats cool. But won’t that make you have diff sets of classes to handle diff hardware ?
[/quote]
It requires JNi code to set up an NIO Native Direct Byte Buffer to begin with. This means that by definition you will have paltform specific code. Beyond that it depends on the native APIs and how they work

You will find more information on this in the JNI notes that come with the JDK.

Edit: I rarely do this. in fact I think its the first time i have, but this is so CLEARLY in the wrong place could I please ask the board ops to move the thread to Newless Cluebies, where it should have been to begin with? Thanks.

Ok i will check out the NIO api when i get the time. But i have to admit im not seeing the big picture for clueless newbes about using it IF we have to do specific JNI code. We could just ignore NIO a create our own JNI code that could be even more optimized for our game without the restrictions of having to suport NIO requirements.

It brings us to the question if having a direct binding to OpenGL and trying to patch the limitations of such aproach with packs like NIO is really a better option than creating a core native 3d engine independent of OpenGL and NIO and specialized to take advantage of Java OO features.

NOTE: When i say independent i mean not having to be one-to-one mapping of structures and functions from OpenGL to Java.

On a slightly related note, recently I had a bunch of data I was using for both rendering and game logic (a bunch or normals in particular). For ease I went with an array of objects for game logic use, and a nio buffer for use when rendering.

But duplicate data always annoys me. Do others tend to duplicate in this way or just use the nio data for both?

That’s (one of the radically different and unrelated) reasons why you want structs ;D. Lets you keep your data in buffers and yet access it in java-friendly manner.

/me ducks and runs for cover

Well yeah, but I was kinda hoping for some practical advice which I can actually use now. :stuck_out_tongue:

I duplicate data and tend to write it out sequentially in one big go to make best use of caches and write combining.

Cas :slight_smile:

[quote]Ok i will check out the NIO api when i get the time. But i have to admit im not seeing the big picture for clueless newbes about using it IF we have to do specific JNI code. We could just ignore NIO a create our own JNI code that could be even more optimized for our game without the restrictions of having to suport NIO requirements.
[/quote]
Yup, your not getting it.

Let me take a step back l now that I know this is a clueless newbie discussion and explain. Lest start with Native Byte Buffers, just one of the NIO features:

In a typical Windows system running a Java application there are three very distinct and seperate hunks of memoy.

There is the device memory, an example of which being the memory on your video card that all geometry and textrues have to get to before you can render.

There is the C heap, which is the memory that the Java heap comes from as well as all memory you allocate in C from JNI.

Then there is the Java Heap, which is Java’s memory. All data new’d in Java comes from the Java Heap.

In the worst case, using JNI, you would have to do the following to get geometry from Java to the video card:

For every Geomrtry Change:

(1) Allocate memory in the Java heap and build your geometry.
(2) Call thorugh JNI (at some cost) to a C side function.
(3) C side function calls back to Java to get the geometry. (Significant cost PLUS a full data copy from the Java heap to the C heap.
(4) C function then calls an openGL function to set that in the video memory (ANOTHER data copy operation ocurrs.)

Now OGL, thansk to Nvidia, now supprots a way to get a “window” into the video card’s memory and write to that directly from C. Using this you could eliminate step 4 by pre-allocating that window and then passing THAT to Java to copy the data into in step 3. This however does nothing about the really expensive part., which is moving the data from the Java heap to the C heap.

NIO introduces Native Direct Byte Buffers. These are sturctures that look like Byte Buffers from the Java side but are really pointers directly into the machine’s memory space.

Combining the vdieo card geoemtry “window” and a native byte buffer, the code looks like this

ONCE:
(1) Call throgh JNI to a C function that gets that video card memory window and wraps a Native Direct Byte Buffer around. It then returns the Natvie Direct Byte Buffer to the Java function that called the Native function, (Modest cost).

For every geometry change.
(1) Write the geoemtry DIRECTLY into video memory from Java using the NDBB.

(2) Call a JNI function once per frame that requires no data and returns no data. All it does is kick the card to render whats already been set into it.

See? You avoid MANY data copies as well as pulling data from the Java heap to the C heap which is quite expensive in of itself.

In short, yes it is.

Your going to have to talk to OGL anyway. And if you use the features of Java correctly its really not appreciably more expensive then calling OGL from C.

And the more code you can do in java, the more portable you are, the less buggy you are., the faster your project is done, and the happier you will be :slight_smile:

It isnt a one to one mapping on the code level. There is a mapping on the API level because the OGL API is proven and there is a huge body of knowledge on how to use OGl effectively already in existance.

But the assumption that every JOGL API call just calls the matching C API call across JNI in a dumb fashion is patently false.

Modern games tend to keep at least two partially seperate representations of the 3D world in memory, even in C. One optimized for render and another optimized for Physcis.

Does that help any?

Yes, the more I think about it it seems unavoidable. A pretty classic speed vs. memory tradeoff really. And we all know which way games tend to lean in that department.

Thinking about it, what I should do is resign myself to keeping a duplicate - at which point I can optimise the for-renderer copy and shove them in vram where drawing will be faster.

I’ve always thought that there were a 1:1 mapping. Whenever you a call a glXXX function, there is a JNI function call. Maybe a little book keeping for the more advanced features like vertex arrays or vbos, but always a JNI call.

Can you explain a little more what is actually going on behinde the scene? Are the functions cached in some way or what?

Well look at that, a simple explanation that compreensibly justifies the use of nio and jogl for games instead of a split c++engine/java solution. See guys it can be done.

The right information to the right people can do wonders in selling java game technology to the sceptics.

You guys have to try and fill the shoes of guys like me who have some knowledge of game design and mostly C++ but very little about how the Java solution works. Just telling someone like me to read the entire NIO doc and JNI doc wont cut.

It may sound too sceptical and unaceptable for some but the way many other potential java game developers see it if a developer can’t cleary answer critical questions like this in a small document that can be understood by outsiders with a minimal knowledge of java gaming tech it will be taken as immature technology. Only after that they will pick up java gaming tech and test it.

When i say try it i mean buidling a prototype game both in C++ and in Java and do extensive benchmarks to catch all strong and weak points.

Thanks Alf. That was a very good explanation. I think you should pin it in the somewhere or make a blog of it.