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
|