gcsaba2
Junior Devvie  
Hello world
|
 |
«
Posted
2005-05-02 13:27:58 » |
|
I see a lot of talk about java.nio on this forum, and I was wondering what's so special about it. After checking around I see it has some buffers, like an IntBuffer. So is an IntBuffer faster than an array?
|
|
|
|
princec
|
 |
«
Reply #1 - Posted
2005-05-02 14:03:42 » |
|
When it comes to sending data to OpenGL, buffers are the only reasonable way to do it in many circumstances, and they are guaranteed fast as well. Other than that you might use them for serverside stuff for incoming client communications. Cas 
|
|
|
|
blahblahblahh
|
 |
«
Reply #2 - Posted
2005-05-02 20:21:06 » |
|
NIO adds a whole feature: direct access to native memory.
When only the best will do, when you've absolutely positively got to transfer every last buffered-byte to/from native memory (as fast as you can).
Great fro graphics cards: write to AGP memory. Great for servers: stream data from native-mem to native-mem using DMA and bypassing the CPU.
|
malloc will be first against the wall when the revolution comes...
|
|
|
Games published by our own members! Check 'em out!
|
|
Jeff
|
 |
«
Reply #3 - Posted
2005-05-02 20:48:05 » |
|
Really this is probably a "clueless newbie" question, but we mgiht as well answer it sicne you posted it here. Native byte buffers are is just oen of the many uses of NIO. It also allows for: -- Non blocking IO (of aprticualr intreest is non-blocking socekts) -- Ways to build copy-less protocol stacks. -- Memory mapped IO There are probbaly some other features Im forgetting. Peruse the Javadocs. Thats the source of all Java knowledge 
|
|
|
|
Mark Thornton
|
 |
«
Reply #4 - Posted
2005-05-03 10:48:25 » |
|
-- Memory mapped IO
The utility of which is seriously limited on Windows. Useless for files which might change size or that you may wish to delete. Peruse the Javadocs. Thats the source of all Java knowledge  There is quite a lot of Java knowledge which can't be found in the JavaDoc's; you have to go and test it. They have also contained misinformation. For example, it took years to convince Sun to change the documentation relating to file locking methods. They seemed unable to understand that their recommended approaches could not be made to work reliably on Windows.
|
|
|
|
gcsaba2
Junior Devvie  
Hello world
|
 |
«
Reply #5 - Posted
2005-05-03 13:52:51 » |
|
Thanks for the replies, now I'd just like to get an answer to my original question:  Is an IntBuffer faster than an array of int?
|
|
|
|
blahblahblahh
|
 |
«
Reply #6 - Posted
2005-05-03 14:47:24 » |
|
Thanks for the replies, now I'd just like to get an answer to my original question:  Is an IntBuffer faster than an array of int? Yes. No. Your question is meaningless. You meant to ask "is X faster than Y at doing Z in environment E?" but your post got cut short 
|
malloc will be first against the wall when the revolution comes...
|
|
|
princec
|
 |
«
Reply #7 - Posted
2005-05-03 16:50:40 » |
|
Yeah, what he said - where do you want to use it and when? Cas 
|
|
|
|
Jeff
|
 |
«
Reply #8 - Posted
2005-05-03 19:04:31 » |
|
Thanks for the replies, now I'd just like to get an answer to my original question:  Is an IntBuffer faster than an array of int? In general, no. Depending on the implementation of NIO on a particular patlrom, just putting numbers in and taking numbers out in Java is likely to be equal to or slower then a simple array. But why do you care? What problema re you trying to sovle? Arrays are blindingly fast for anything other then non-sequential access and even there they arent likely to be your real bottleneck ulnes yo uare doing MASSIVE amounst of random access (ie an MPEG video codec.) This really feels like a premature optimization thing.
|
|
|
|
gcsaba2
Junior Devvie  
Hello world
|
 |
«
Reply #9 - Posted
2005-05-04 10:36:23 » |
|
Well I'm still designing the game I will be writing, so I wanted to know what my options were. If I would be having an array of 1 million integers and I'd have to go through it every time the mouse cursor moves (for example), then I'd like to know if there's something faster than an array. Of course I wouldn't have to pass through the entire array, only in the worst possible case  Let's say that my game is being played on a 800x600 screen, and in that case the game map would be 20x10 screens. Now, this would not be a dynamic map, but it would be drawn and saved to a file, and then during gameplay it would be read from. Let's say that the uncompressed size of this bitmap would be 2 GB, so it would be impossible to keep the entire bitmap in the memory. How do I solve this? I was looking at memory mapped buffers provided by Java, is this what I need? I would only need a tiny portion of the bitmap at one time, let's say 5 MB, so I could keep that in the memory, while the rest would stay (compressed) in a file. Or another option would be to split the bitmap into several smaller files, and then do the memory management myself, meaning I would dump one image if it would be out of screen
|
|
|
|
Games published by our own members! Check 'em out!
|
|
princec
|
 |
«
Reply #10 - Posted
2005-05-04 11:21:58 » |
|
You're still not quite answering the question. When we're talking performance tuning, you can only answer a question for a very specific problem. For your map problem, for example: this has nothing to do with ints or arrays at all. Your problem is one of paging chunks in and out of RAM in a timely fashion. Therefore you ought to be looking at splitting the map up into teeny little chunks and maintaining a working set of pages according to what you need to display. The precise speed of it then depends on the precise requirements of your map (and in any case will probably be totally disk IO limited anyway, rendering nearly all minor tweakage irrelevant) Cas 
|
|
|
|
gcsaba2
Junior Devvie  
Hello world
|
 |
«
Reply #11 - Posted
2005-05-04 11:42:53 » |
|
You're still not quite answering the question. When we're talking performance tuning, you can only answer a question for a very specific problem. I know I'm sorry, I guess I don't precisely know what I want. I find so many new options every day and I would like to check them all out before choosing the right one. Let's say I have a 2 GB bitmap, and I split it into 1 million pieces, where each piece is a tile. So one tile then is roughly 1 KB. If that tile is visible I paint it on the proper place; if it's not visible then it should not be in the memory. Or perhaps if the tile is too close to the visible tiles, so that when I scroll 5 pixels to the left it will be visible, then it should be kept in the memory for fast access. I could create 1 million files and then read them when necessary. This I can imagine how to do, but I guess it would be slow or awkward. Or I could have a 2 GB image containing all the pictures, compress it into let's say 200 MB, read that file into a mapped buffer, and then use only portions that are needed. This sounds neat but I'm not sure how to do it, or even if it can be done. I'm looking at Europa Universalis 2 where they did have a 2 GB image of the world and they read only parts from it when necessary. I would like to have something similar. 
|
|
|
|
princec
|
 |
«
Reply #12 - Posted
2005-05-04 12:14:03 » |
|
Because the file is so huge, taking up the entire address space of a typical 32bit desktop OS, you can't memory map it. What you need to do is split the map up into tiles, compress each tile individually, then I expect the best way to store it on the disk is one file per tile and reference them in some kind of LRU cache which holds at most, say, 100 tiles. Furthermore I suggest that the LRU cache loads the 8 adjacent tiles for any request in the background. You can afford to spend, say, 16MB of actual RAM holding map tiles, so make sure that about 25 tiles fit in 16MB and size them accordingly. That should allow you to scroll around freely with too many cache misses provided your scroll speed is slower than a disk load. I expect you'll find that a 256x256 tile will be ideal  Cas 
|
|
|
|
Deadcow
Senior Newbie 
Back from beyond ... Moo!
|
 |
«
Reply #13 - Posted
2005-05-04 14:01:43 » |
|
Cas, the map method of a FileChannel allow you to map only a part of the file so what's the problem with 2GB files ?
|
|
|
|
princec
|
 |
«
Reply #14 - Posted
2005-05-04 14:29:26 » |
|
Because it'd still be pretty pointless - what he wants to do is treat the whole 2GB file as a single bit of memory to make life easier. However - that means having a 2GB file on the harddisk which isn't very nice, and as he's just going to have to map bits of it anyway - the best solution is to chop it up first, then compress the bits. This will not only be easy to do, but it'll be efficient too. Cas 
|
|
|
|
Mark Thornton
|
 |
«
Reply #15 - Posted
2005-05-04 17:00:39 » |
|
Cas, the map method of a FileChannel allow you to map only a part of the file so what's the problem with 2GB files ? In addition to Cas's comments, there is also a problem when you want to map another part of the fail. This will fail if too much of the memory previously mapped has yet to be released. Nor is there any way to force this memory to be released even if it is collectable. Finally there seems to be a bug with Java+Windows where memory mapped regions overlap (this includes cases where your current request overlaps a previous request that has yet to be cleared although no longer reachable). My conclusion is that, on Windows at least, memory mapping through Java has all the utility of a chocolate teapot. This is especially unfortunate given that I have successfully used memory mapping from C++ on Windows.
|
|
|
|
Orangy Tang
|
 |
«
Reply #16 - Posted
2005-05-04 20:16:29 » |
|
On a more practical note, its not going to be fun editing, saving, moving etc. with a whopping 2gb file. For the sake of your sanity alone split it up into seperate files. Equally with patching, replacing a single 800x600 image is a piece of cake, but manually splicing in a section into a 2gb file is not going to be fun. The alternative of just replacing the entire file is too hideous to even contemplate.
|
|
|
|
Jeff
|
 |
«
Reply #17 - Posted
2005-05-09 18:43:02 » |
|
Because the file is so huge, taking up the entire address space of a typical 32bit desktop OS, you can't memory map it. What you need to do is split the map up into tiles, compress each tile individually, then I expect the best way to store it on the disk is one file per tile and reference them in some kind of LRU cache which holds at most, say, 100 tiles. Furthermore I suggest that the LRU cache loads the 8 adjacent tiles for any request in the background.
Its worth noting that LRU caches in java are trivial. This wil lalos be alot faster then mmeory mappign it all. There is still copying goign on reading amemory mapped file into the Java Heap space to use it. HashMap + SoftReference == memory sensastive LRU cache.
|
|
|
|
Jeff
|
 |
«
Reply #18 - Posted
2005-05-09 18:46:02 » |
|
Well I'm still designing the game I will be writing, so I wanted to know what my options were. If I would be having an array of 1 million integers and I'd have to go through it every time the mouse cursor moves (for example), then I'd like to know if there's something faster than an array.
Depedns on for what? For a search? Sure there are lots faster data structures in ANY language. What you are really doing here is prematurely optimizing. That never results in the fastest code. Design your code for clarity and good seperation of functiosn and then you can tune what REALLY matters when you find out what that is. And you wont find out til your first cut is written and profiled. Thats a promise.
|
|
|
|
swpalmer
|
 |
«
Reply #19 - Posted
2005-05-09 21:57:00 » |
|
There is still copying goign on reading amemory mapped file into the Java Heap space to use it. Seriously? I had always figured that would only be done through a Direct Byte Buffer precisely to avoid the need to copy. It would give you very "direct" access to the OS memory mapping
|
|
|
|
Jeff
|
 |
«
Reply #20 - Posted
2005-05-10 05:09:26 » |
|
Seriously? I had always figured that would only be done through a Direct Byte Buffer precisely to avoid the need to copy. It would give you very "direct" access to the OS memory mapping
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.
|
|
|
|
zingbat
|
 |
«
Reply #21 - Posted
2005-05-10 08:17:18 » |
|
Yes but you guys didn't answered the mans orginal question. What is nio good for ?  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.
|
|
|
|
princec
|
 |
«
Reply #22 - Posted
2005-05-10 08:41:12 » |
|
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 
|
|
|
|
zingbat
|
 |
«
Reply #23 - Posted
2005-05-10 11:05:17 » |
|
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 ?
|
|
|
|
blahblahblahh
|
 |
«
Reply #24 - Posted
2005-05-10 12:06:01 » |
|
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 ?
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.
|
malloc will be first against the wall when the revolution comes...
|
|
|
princec
|
 |
«
Reply #25 - Posted
2005-05-10 13:27:20 » |
|
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 
|
|
|
|
Jeff
|
 |
«
Reply #26 - Posted
2005-05-10 18:34:23 » |
|
Yes but you guys didn't answered the mans orginal question. What is nio good for ?  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."
|
|
|
|
Jeff
|
 |
«
Reply #27 - Posted
2005-05-10 18:37:06 » |
|
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 ?
Um... did yo umiss a post? To quote myself... on May 3rd, 2005, 8:52am, gcsaba2 wrote: Thanks for the replies, now I'd just like to get an answer to my original question: Grin Is an IntBuffer faster than an array of int?
I respond: In general, no. Depending on the implementation of NIO on a particular patlrom, just putting numbers in and taking numbers out in Java is likely to be equal to or slower then a simple array. But why do you care? What problema re you trying to sovle? Arrays are blindingly fast for anything other then non-sequential access and even there they arent likely to be your real bottleneck ulnes yo uare doing MASSIVE amounst of random access (ie an MPEG video codec.) This really feels like a premature optimization thing.
|
|
|
|
zingbat
|
 |
«
Reply #28 - Posted
2005-05-10 19:33:36 » |
|
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 ?
|
|
|
|
Jeff
|
 |
«
Reply #29 - Posted
2005-05-10 20:09:45 » |
|
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 ?
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.
|
|
|
|
|