Re: [sdljava-users] Usage example for glGetDoublev
Status: Beta
Brought to you by:
ivan_ganza
From: Gregor <Gre...@gm...> - 2005-09-13 23:44:33
|
Your numbers are pretty impressive. May I ask what CPU you used for these?= =20 I've tested with the Sun J2SDK 1.5.0.04 on an Athlon XP 1800+ with 1GB main= =20 memory, in case that matters. I forgot to mention that in my original email= =2E=20 Sorry about that. And I really need a compiler/VM combo that can deal with= =20 generics as my code is littered with uses of the new java.util generics. I= =20 don't know if jamvm or gcj are there yet. There seems to be a minor misunderstanding about glVertex3d and similar: th= e=20 size of the expected data array is fixed. For example glVertex3f expects 3= =20 floats and glVertex2d expects 2 doubles, etc... So for the majority of thes= e=20 functions you really only pass fixed small amounts of data. And about the benchmark: I wrote and ran that in about half a hour this=20 morning and there's no need to overly copyright such little amount of work = as=20 that actually was. So give it whatever license you might see fit. I'm fine= =20 with the GPL in particular if you add the right headers for me :-). Ivan: Thanks for these changes. And I fully understand the need for scripts= to=20 generate the source code. The number of functions following the same patter= n=20 in OpenGL is insane and anyone not autogenerating the bindings for them wou= ld=20 be a fool. Thanks for your support to both of you! Regards, Gregor On Wednesday 14 September 2005 00:32, Robert Schuster wrote: > Hi Gregor, > this is an impressive nice benchmark. Look what our free VMs can achieve: > > rob@linkist ~/tmp/test/bench/buffer-vs-arrays $ LD_LIBRARY_PATH=3D. gij > Benchmark running Test Benchmark$TestArrayReallocate for 1000000 times > result: 2705 > running Test Benchmark$TestArrayAllocateOnce for 1000000 times > result: 2242 > running Test Benchmark$TestByteBufferReallocate for 1000000 times > result: 4329 > running Test Benchmark$TestByteBufferAllocateOnce for 1000000 times > result: 1047 > > (This is GCJ 4.0 somewhat.) > > rob@linkist ~/tmp/test/bench/buffer-vs-arrays $ LD_LIBRARY_PATH=3D. jamvm > Benchmark running Test Benchmark$TestArrayReallocate for 1000000 times > result: 1825 > running Test Benchmark$TestArrayAllocateOnce for 1000000 times > result: 1443 > running Test Benchmark$TestByteBufferReallocate for 1000000 times > result: 7916 > running Test Benchmark$TestByteBufferAllocateOnce for 1000000 times > result: 278 > rob@linkist ~/tmp/test/bench/buffer-vs-arrays $ > > (Both are interpreted only. JamVM has a handcrafted JNI implementation th= at > really outperforms the JDK) > > As a comparison my JDK 1.5.0 results: > LD_LIBRARY_PATH=3D. /opt/sun-jdk-1.5.0/bin/java Benchmark > running Test Benchmark$TestArrayReallocate for 1000000 times > result: 484 > running Test Benchmark$TestArrayAllocateOnce for 1000000 times > result: 386 > running Test Benchmark$TestByteBufferReallocate for 1000000 times > result: 15891 > running Test Benchmark$TestByteBufferAllocateOnce for 1000000 times > result: 287 > > However your point seems to be valid. Frequent allocations of direct > buffers kill performance. In my opinion this is very sad for Java because > it means > > if (amountOfData < someMagicValue) { > GL.glVertex3fv(new int[] { foo, baz, bar, ... }); > } else { > IntBuffer b =3D BufferUtils.createBuffer(...); > b.put(...); > GL.glVertex3fv(b); > } > > Gregor would you mind giving your benchmark a GPL or GPL-compatible licen= se > so I may be allowed to put it into mauve (the free test suite)? I am sure > Robert Lougher (JamVM) and the GCJ team is pretty interested about these > results. > > Oh yes and you're right. For maximum control over performance GLJava shou= ld > provide OpenGL's v-functions with Java arrays exactly in the way you did = it > in the benchmark. And then the Javadoc should mention when to use which > version ... > > cu > Robert > > Gregor M=C3=BCckl wrote: > > Hi! > > > > I've finally tried to benchmark java arrays and direct buffers in small > > buffers of the size that would typically appear in OpenGL apps. The > > results of the runs on my computer are: > > > > gregor@goose ~/progs/nio-benchmark $ LD_LIBRARY_PATH=3D. java Benchmark > > running Test Benchmark$TestArrayReallocate for 1000000 times > > result: 1033 > > running Test Benchmark$TestArrayAllocateOnce for 1000000 times > > result: 817 > > running Test Benchmark$TestByteBufferReallocate for 1000000 times > > result: 32803 > > running Test Benchmark$TestByteBufferAllocateOnce for 1000000 times > > result: 560 > > gregor@goose ~/progs/nio-benchmark $ LD_LIBRARY_PATH=3D. java Benchmark > > running Test Benchmark$TestArrayReallocate for 1000000 times > > result: 1034 > > running Test Benchmark$TestArrayAllocateOnce for 1000000 times > > result: 776 > > running Test Benchmark$TestByteBufferReallocate for 1000000 times > > result: 34588 > > running Test Benchmark$TestByteBufferAllocateOnce for 1000000 times > > result: 591 > > gregor@goose ~/progs/nio-benchmark $ LD_LIBRARY_PATH=3D. java Benchmark > > running Test Benchmark$TestArrayReallocate for 1000000 times > > result: 984 > > running Test Benchmark$TestArrayAllocateOnce for 1000000 times > > result: 768 > > running Test Benchmark$TestByteBufferReallocate for 1000000 times > > result: 35151 > > running Test Benchmark$TestByteBufferAllocateOnce for 1000000 times > > result: 615 > > gregor@goose ~/progs/nio-benchmark $ LD_LIBRARY_PATH=3D. java Benchmark > > running Test Benchmark$TestArrayReallocate for 1000000 times > > result: 1093 > > running Test Benchmark$TestArrayAllocateOnce for 1000000 times > > result: 847 > > running Test Benchmark$TestByteBufferReallocate for 1000000 times > > result: 35321 > > running Test Benchmark$TestByteBufferAllocateOnce for 1000000 times > > result: 623 > > gregor@goose ~/progs/nio-benchmark $ LD_LIBRARY_PATH=3D. java Benchmark > > running Test Benchmark$TestArrayReallocate for 1000000 times > > result: 730 > > running Test Benchmark$TestArrayAllocateOnce for 1000000 times > > result: 575 > > running Test Benchmark$TestByteBufferReallocate for 1000000 times > > result: 22455 > > running Test Benchmark$TestByteBufferAllocateOnce for 1000000 times > > result: 438 > > > > The source code for the benchmark is included. This clearly shows that > > direct buffers are really only viable if you can avoid their allocation. > > But now the problem is that caching ByteBuffers would add considerable > > overhead to the results of the last measurements in both sourcecode > > complexity and runtime. Furthermore, caching unused data structures in > > Java is especially bad design and any suggestion to that end can easily > > be seen as a sign of bad design elsewhere. And in reality it may really > > not be feasible. I'm writing a 3d modelling tool which cannot apply > > proper rendering optimizations because the geometry may essentially be > > anything and change at any time to anything else. So I have to use > > thousands of calls to glVertex3d(v) and similar. > > > > Compared to direct buffers even the reallocated arrays don't have so mu= ch > > added overhead. So I strongly suggest that you implement arrays at least > > as an alternative interface. It's easy to overload functions in Java, so > > this is not a problem. > > > > The source code to the benchmark is appended. > > > > Regards, > > Gregor > > > > On Tuesday 13 September 2005 04:17, Ivan Z. Ganza wrote: > >>Thanks for the very detailed information :-) > >> > >>The helpful class is sdljava.util.BufferUtil...which Robert kindly > >>coded. Interesting to have a look at the code inside... > >> > >>Please let us know if your able to make it work Gregor. > >> > >>-Ivan/ > >> > >>Robert Schuster wrote: > >>>Hi, > >>>I just want to jump into the discussion because I was one of the perso= ns > >>>who suggested Ivan to use NIO buffers instead of Java arrays (and I ha= ve > >>>some small background about the topic from JNI and GNU Classpath > >>> coding). > >>> > >>>>The biggest buffer I use that way is there to store a matrix of > >>>>4x4 doubles, that is, 128 bytes. > >>> > >>>Perfect. This is really the point where you can use NIO buffers. It may > >>> be look odd to you but a regular Java array is more troublesome than a > >>> NIO buffer. The buffer is an object denoting a certain memory region. > >>> Therefore you can think of it as a thin wrapper around a normal C arr= ay > >>> (or memory region that allocated with malloc/calloc). > >>> > >>>A Java array is something that lifes inside the JVM and can be > >>> implemented very differently. NIO buffers and Java arrays have very > >>> similar JNI functions to interact with them. Both have a function whi= ch > >>> returns a pointer so that you can modify the data in C-style. However > >>> the array access function explicitly states that you *may* receive the > >>> pointer to a copy of the original data (remember that Java arrays life > >>> in the JVMs heap and may be moved around because of garbage collection > >>> and memory compaction). This won't happen with NIO buffers. > >>> > >>>If you have a feeling that frequent bytebuffer instantiations would ha= rm > >>>the performance of your application then please have a look whether you > >>>may not solve this problem in a different way (e.g. pooling buffers or > >>>the like). > >>> > >>>>Using byte buffers may be a valid approach when working on large, > >>>> uniform amounts of data like framebuffers. But that is not the case > >>>> with geometry data for OpenGL. Using vertex arrays is almost out of > >>>> question for me since the geometry data I have is very dynamic in > >>>> every way. > >>> > >>>Definitely not. NIO buffers can be used wherever interaction with nati= ve > >>>machinery is involved. I once wrote a jinput plugin which uses the Lin= ux > >>>kernel's input system to access mouse/keyboard/joypad etc (You can find > >>>the sources in the respective forums at javagaming.org). It makes heavy > >>>use of NIO buffers even for such small amounts of data (key/button/axes > >>>states) and I think it is a big win that the system's kernel can write > >>>into the memory which it shares with my Java application. > >>> > >>>>Well, this is not trying to be a rant. I'm just not yet convinced that > >>>>this is the right approach. It looks like far too much overhead to me, > >>>>making all the OpenGL functions taking (small) arrays practically > >>>>useless. > >>> > >>>Well, in which way could they be implemented otherwise? At one point y= ou > >>>will forced to create a buffer in memory (probably C). If you hand over > >>>the data in Java arrays and copy it over into a malloc'ed memory region > >>>then this would hit performance seriously (You need one copy operation > >>>and one time malloc/free in GLJava's code.) With NIO buffers the JNI > >>>implementation would simply return the buffer's pointer and call the > >>>OpenGL function. The handling of the buffer (recreate it every time or > >>> do some pooling) is up to you - the application programmer. > >>> > >>>>Maybe some > >>>>benchmarking is in order to get some definitive answers, but I don't > >>>> have enough time for that. > >>> > >>>Well I try to prove it with a bit of pseudo code. (I use pseudo code > >>>because I dont know the JNI function names by heart. They are very > >>>tedious ...) > >>> > >>> > >>>1. With Java arrays > >>>GL.java > >>> > >>>public class GL { > >>> public native setSomethingv(int[] foo); > >>>} > >>> > >>>net_sf_GL.c: > >>> > >>>setSomethingv(jvm, jobject java_array){ > >>> > >>> jint* thevalues =3D JVM_get_pointer_to_java_array(java_array); // may > >>>copy > >>> > >>> int size =3D JVM_get_size_of_java_array(java_array); > >>> > >>> int* buffer =3D malloc(sizeof(int) * size); > >>> > >>> memcopy(thevalues -> buffer, size * sizeof(int)); > >>> > >>> GLsetSomething(buffer); > >>> > >>> JVM_release_access_to_java_array(java_array); > >>>} > >>> > >>>2. With NIO buffers > >>> > >>>public class GL { > >>> public native setSomethingv(IntBuffer foo); > >>>} > >>>net_sf_GL.c: > >>> > >>>setSomethingv(jvm, jobject nio_buffer){ > >>> > >>> jint* thevalues =3D JVM_get_pointer_of_nio_buffer(nio_buffer); > >>> > >>> GLsetSomething(thevalues); > >>> > >>> JVM_release_access_to_java_array(java_array); > >>>} > >>> > >>>(I am broadly ignoring any type conversion oddities here.) > >>> > >>>Btw: There is a utility class in GLJava that creates direct Integer, > >>> Long, Short, Double and Float buffers in one method call (In fact eve= ry > >>> newer OpenGL binding* has these methods ...) > >>> > >>>cu > >>>Robert > >>> > >>>* JOGL, LwJGL > >>> > >>> > >>>------------------------------------------------------- > >>>SF.Net email is Sponsored by the Better Software Conference & EXPO > >>>September 19-22, 2005 * San Francisco, CA * Development Lifecycle > >>>Practices Agile & Plan-Driven Development * Managing Projects & Teams * > >>>Testing & QA Security * Process Improvement & Measurement * > >>>http://www.sqe.com/bsce5sf > >>>_______________________________________________ > >>>sdljava-users mailing list > >>>sdl...@li... > >>>https://lists.sourceforge.net/lists/listinfo/sdljava-users > >> > >>------------------------------------------------------- > >>SF.Net email is Sponsored by the Better Software Conference & EXPO > >>September 19-22, 2005 * San Francisco, CA * Development Lifecycle > >> Practices Agile & Plan-Driven Development * Managing Projects & Teams * > >> Testing & QA Security * Process Improvement & Measurement * > >> http://www.sqe.com/bsce5sf > >> _______________________________________________ > >>sdljava-users mailing list > >>sdl...@li... > >>https://lists.sourceforge.net/lists/listinfo/sdljava-users > > ------------------------------------------------------- > SF.Net email is sponsored by: > Tame your development challenges with Apache's Geronimo App Server. > Download it for free - -and be entered to win a 42" plasma tv or your very > own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php > _______________________________________________ > sdljava-users mailing list > sdl...@li... > https://lists.sourceforge.net/lists/listinfo/sdljava-users |