Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (524)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (592)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 2 [3] 4 5 ... 7
  ignore  |  Print  
  Once again! fast MappedObjects implementation  (Read 31716 times)
0 Members and 1 Guest are viewing this topic.
Offline Spasi
« Reply #60 - Posted 2011-06-29 19:12:43 »

1  
2  
3  
4  
CLMem mem = clCreateBuffer(clContext, CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, nodes * Matrix4f.SIZEOF, errorCode);
ByteBuffer data = MappedObjectUnsafe.newBuffer(mem.getInfoLong(CL_MEM_HOST_PTR), (int)mem.getInfoSize(CL_MEM_SIZE));
Matrix4f matrices = Matrix4f.map(data);
Matrix4f.setIdentity(matrices, nodes);


Mapped access to CPU addressable PCIe memory? Check. Wink

More requests:

- A getter for the mapped buffer in MappedObject will be useful. It's one less reference to keep around when user code needs to pass the buffer to GL/CL.

- A .map(address, capacity) could be added, that would do the equivalent of lines 2-3 in the code above. MappedObjectUnsafe could be made package-private as well.
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #61 - Posted 2011-06-29 20:02:30 »

Interesting to see how you put my lib to use Smiley

What you're doing, is rather dangerous at the moment. Once the GC deems the manipulated ByteBuffer collectable, it will free the address it's pointing to, which is probably an illegal action, because that memory is not supposed to made available again through malloc(..) and last but not least  might also be freed by the driver.

At least, that's what little I (think I) know of what happens within ByteBuffer and how memory gets reused.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #62 - Posted 2011-06-29 20:24:00 »

I think the best solution would be to never release the buffers, by storing them in some hidden collection, forever, maybe adding a method to release them.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Spasi
« Reply #63 - Posted 2011-06-29 20:25:55 »

Nope, it's safe because of .duplicate(). It uses a different constructor that doesn't set a Deallocator, so Unsafe's freeMemory won't be called when the object gets garbage collected. It's the same with JNI's NewDirectByteBuffer.
Offline Spasi
« Reply #64 - Posted 2011-06-29 20:34:48 »

Interesting to see how you put my lib to use Smiley

Tbh, I would have created something like this on my own eventually. I'm currently doing research for an upcoming project that kinda requires fast buffer access. It was very fortunate that you started working on this now, saves me time and I'd never have thought about field access with bytecode transformation, so it's a double win for me. That's why I'm trying to contribute as much as I can, I need this to be as robust and complete as possible. I'm also pretty sure it's not only me and Princec that are really happy about this library being available.
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #65 - Posted 2011-06-29 20:37:29 »

- A getter for the mapped buffer in MappedObject will be useful. It's one less reference to keep around when user code needs to pass the buffer to GL/CL.
Keep in mind that the buffer is not necessarily linked to the baseAddress field, which might be very confusing.



Nope, it's safe because of .duplicate(). It uses a different constructor that doesn't set a Deallocator, so Unsafe's freeMemory won't be called when the object gets garbage collected. It's the same with JNI's NewDirectByteBuffer.
Okay, but it would still need a reference to its 'parent' buffer, to prevent its memory region from being freed.

I should probably look into the sourcecode to see what's happening there.



Interesting to see how you put my lib to use Smiley

Tbh, I would have created something like this on my own eventually. I'm currently doing research for an upcoming project that kinda requires fast buffer access. It was very fortunate that you started working on this now, saves me time and I'd never have thought about field access with bytecode transformation, so it's a double win for me. That's why I'm trying to contribute as much as I can, I need this to be as robust and complete as possible. I'm also pretty sure it's not only me and Princec that are really happy about this library being available.

Your 'contributions' are basically the only reason I keep updating the lib. It seems like nobody else cares, and I don't really plan on using this lib myself Smiley

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Spasi
« Reply #66 - Posted 2011-06-29 20:53:30 »

Keep in mind that the buffer is not necessarily linked to the baseAddress field, which might be very confusing.

I guess you mean when there's an offset involved? I can live with that.

Okay, but it would still need a reference to its 'parent' buffer, to prevent its memory region from being freed.

Indeed, there's a "viewedBuffer" reference.
Offline princec

« JGO Spiffy Duke »


Medals: 422
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #67 - Posted 2011-06-29 21:30:29 »

Your 'contributions' are basically the only reason I keep updating the lib. It seems like nobody else cares, and I don't really plan on using this lib myself Smiley
I'm watching it carefully for the dust to settle so I can go and have a poke around it! My sprite engine is annoyingly much slower than it should be thanks to the relative slowness of filling data up in the buffers, so I'm interested to see how much faster (and nicer looking!) it can be made to be with this.

Cas Smiley

Offline concerto49

Junior Devvie





« Reply #68 - Posted 2011-06-30 00:27:45 »

I'm following this closely too.

High performance, fast network, affordable price VPS - Cloud Shards
Available in Texas, New York & Los Angeles
Need a VPS Upgrade?
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 78
Projects: 15


★★★★★


« Reply #69 - Posted 2011-06-30 09:29:01 »

I'm following this closely too.

me three Smiley
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline divxdede

Junior Devvie





« Reply #70 - Posted 2011-06-30 09:55:37 »

me too, but only for interrest on the technical part, not really for using it.
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #71 - Posted 2011-06-30 10:54:29 »

well, you'd need to license it for your games then - CC-NC...

Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #72 - Posted 2011-06-30 11:45:16 »

well, you'd need to license it for your games then - CC-NC...
That doesn't mean that I'd charge everybody for a commercial license... poor indies make an excellent exception Smiley

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline nsigma
« Reply #73 - Posted 2011-06-30 13:04:53 »

well, you'd need to license it for your games then - CC-NC...
Bit OT, but I hate that Non-Commercial clause.  It's so misunderstood and ill-defined both generally and legally - just look at all the research and discussions around it when being ported to different jurisdictions.  If that's what you want, why not GPL + commercial?  Worked for MySQL (getting bought up and bolloxed up by Oracle is an optional extra! Grin )

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #74 - Posted 2011-06-30 14:26:06 »

I might change it soon, after some research. Let's not derail this thread into a license discussion. Smiley

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #75 - Posted 2011-07-04 18:24:53 »

Quote
http://indiespot.net/files/published/mappedobject-0.6.jar (view source)
Main-class: eden.mapped.TestMappedObject
JARs asm-3.2.jar and asm-util-3.2.jar (asm.ow2.org) must be on the classpath.

I coded mapped ByteBuffers by turning the GETFIELD into bytecode that creates a new ByteBuffer, located at the proper memory region:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
@MappedType(sizeof = 64)
public class MappedSomething extends MappedObject
{
   @MappedField(byteOffset = 0)
   public int        used;

   @MappedField(byteOffset = 4, byteLength = 64 - 4)
   public ByteBuffer data;

   @Override
   public String toString()
   {
      return "MappedSomething[" + used + "]";
   }
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
      MappedSomething some = MappedSomething.malloc(4);

      if (some.data == some.data)
         throw new IllegalStateException("should be two distinct ByteBuffers");

      ByteBuffer buf = some.data;  // creates new ByteBuffer instance, it will always point to view #0

      some.view++;

      buf = some.data;  // creates new ByteBuffer instance, it will always point to view #1


It's quite convenient this way, but the creation of the ByteBuffer adds some overhead. Emo



Also, for traversing N mapped objects, use:
1  
2  
3  
4  
5  
6  
for(int i=0; i<N; i++)
{
    mapped.view = i;

    // stuff
}

not:
1  
2  
3  
4  
for(int mapped.view=0; mapped.view<N; mapped.view++)
{
    // stuff
}

maybe I will add an Iterator/Iterable for the convenient for-each loop.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Spasi
« Reply #76 - Posted 2011-07-04 19:21:45 »

Could you drop .duplicate() from .backingByteBuffer()? The library doesn't depend on the ByteBuffer state so I don't think there's a reason for the extra allocation there.
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #77 - Posted 2011-07-04 19:31:31 »

Fair enough. I updated it under version 0.6, as it's a rather minor update.

Further, I added support for enhanced-for:
1  
2  
3  
4  
      for (MappedSomething item: foreach(mapped, viewCount))
      {
         System.out.println("item.view=" + item.view);
      }

which is a static import of MappedObject.foreach

Note that mapped==item, if you want an independant view, use dup()
Regardless of the initial value of 'view', you will iterate: [0..viewCount>
After the foreach, the view of 'mapped' == 'viewCount-1' (the last valid view, basically to prevent a native crash, when accessed after the loop!)

If anybody knows how to get this working with an instance-method, let me know. Pointing


I also added MO.slice() which is identical to MO.dup(), except it does:
   dst.baseAddress=src.viewAddress
which means is has similar characteristics as ByteBuffer.slice()


Bugfix in 0.6:
  • copy/paste bug in jput(..) and iput(..)

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #78 - Posted 2011-07-04 20:09:49 »

@Spasi: sent you a PM.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #79 - Posted 2011-07-05 01:03:03 »

So uh, I still don't get what the point of this library is Tongue

Offline Roquen
« Reply #80 - Posted 2011-07-05 06:04:41 »

Structs!  What I don't get is why there is so little interest in an official array of structs language addition.
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #81 - Posted 2011-07-05 07:58:18 »

Structs!  What I don't get is why there is so little interest in an official array of structs language addition.
All RFEs in that direction have been either closed or ignored, so it's obvious at least Sun couldn't care less. Maybe Oracle will, but it would be a major rewrite of the language, would require new bytecodes. So it'd probably require Java 2.0, which would be tough for the marketing department, as we're on 6.0 already Smiley

Easiest solution is to hack it in...

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline concerto49

Junior Devvie





« Reply #82 - Posted 2011-07-05 08:11:07 »

It's not that Sun doesn't care about Struts. Struts shouldn't be needed language wise because what Riven proposed here is an optimization that should be done at the JVM level. Sun/Oracle chose this way to not break backwards compatibility and provide the performance benefit. Although slowly, they are working on it, e.g. escape analysis.

High performance, fast network, affordable price VPS - Cloud Shards
Available in Texas, New York & Los Angeles
Need a VPS Upgrade?
Offline Riven
« League of Dukes »

« JGO Overlord »


Medals: 833
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #83 - Posted 2011-07-05 08:33:14 »

You absolutely positively cannot let the JVM figure this out.

Escape analysis has nothing to do with it either. There is a fundamental difference between stack-allocation and structs, eventhough structs can be allocated on the stack. Structs can be used for giving an existing memory region new meaning, while escape analysis only prevents the creation of new instances.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline princec

« JGO Spiffy Duke »


Medals: 422
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #84 - Posted 2011-07-05 08:41:53 »

IMHO the idea of mapped objects is/was the very best solution provided the bytecode executed fast enough, and lo and behold, here we have what looks like a working implementation.

Cas Smiley

Offline gouessej
« Reply #85 - Posted 2011-07-05 10:33:16 »

Hi!

Can it be used to improve the performances of 3D scenegraphs, for example those using javax.vecmath or something similar?

Is the CCPL GPL-compatible?

Do you have a typical test case in which we would like to "transfer" a set of values from the CPU to the GPU and vice versa by using your API and any OpenCL binding?

Thank you very much for sharing your source code.

Offline Spasi
« Reply #86 - Posted 2011-07-05 10:49:07 »

Riven, the library needs to ignore static fields on mapped classes. Adding this:

1  
2  
if ( (field.getModifiers() & Modifier.STATIC) != 0 )
      continue;


in MappedObjectTransformer.java, line 52, should do it.

I'll try to explain the benefits that this library provides:

- Reduced memory consumption. Every Java object has some memory overhead; the reference to the object takes 4-8 bytes and then there's whatever padding/alignment the JVM applies to the class fields. Arrays can be tricky as well (compare the memory usage of int[256] and int[128][2]). This overhead becomes significant when the objects are small and you have lots of them. In the context of game development the usual classes that create problems are vectors, matrices, sprite data, etc. By using the mapping this library provides, the object overhead is gone, you only have the data itself.

- Since there are no objects, the GC has much less work to do. In a way, we get explicit memory management, which is something Java game developers have always wanted. You may argue that this is a bad idea and that Java requires no such thing, in which case I will simply point you to Terracotta's BigMemory. Enterprise developers often face very similar problems to game developers, only at a much greater scale. A full GC on a multi-gigabyte heap is catastrophic when you require millisecond responses to thousands of users. Kinda like a game, you can't afford to drop a frame due to GC. And even though modern JVMs have super-efficient collectors, it's still a problem game developers face frequently. Obviously Terracotta chose to implement BigMemory with serialization, which makes sense for that environment and requires minimum code changes. With Riven's library there's no serialization, the data is the object. Also, memory management is "half-explicit", that is, you do have to allocate the buffer to map, but you never have to "free" it, it still works like normal Java, make it null and it's gone. This is actually beneficial for game development, since you often need to allocate/deallocate objects in batches anyway (e.g. on level start/end).

- Continuous allocations stay that way. This may not be obvious to many Java programmers, but if you consider code like:

1  
2  
3  
Vector4f[] vectors = new Vector4f[256];
for ( int i = 0; i < vectors.length; i++ )
    vectors[i] = new Vector4f();


you might expect that these vectors you just allocated are in continuous blocks in memory. Well, they may be for a while, but what happens when the objects get promoted from eden to tenured, while going through the survivor stages? Exactly, data locality is gone. You may get lucky, but really, it's not deterministic and you don't know what you will end-up with. This may sound like a GC implementation detail and the truth is that JVM engineers are currently working on a solution, but don't expect it before Java 8. Anyway, having continuous data is very important for getting the most out of the CPU caches, so that's a nice performance benefit.

- This should be really obvious to anyone who has written OpenGL/CL code using a Java binding, any time you need interaction between Java data structures and OpenGL/CL buffers, it's a mess. Not only do you have to copy data to and from buffers, the code is ugly as hell. Even C looks elegant in comparison. No point analyzing this further, you get better performance (no copies necessary) and super-sweet code (POJOs + managing the mapped buffer view offset). For me this justifies the library even if you ignore the other benefits.
Offline Roquen
« Reply #87 - Posted 2011-07-05 11:26:02 »

@Riven: I wouldn't even care too much about low level support.  I'd be happy with sugar.  Implementing array of structures would be easier than some of the stuff that currently on the table IHMO.  I think the real problem is that it's not very OO and thus must be bad or something.  (Even though Java is a pretty weak OO language...not that this is bad or anything.)

In addition to stuff mentioned by Spasi, it's difficult to impossible to implement efficient cache obvious methods in Java the high level language ATM...AoS would go a long way to fixing that.
Offline princec

« JGO Spiffy Duke »


Medals: 422
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #88 - Posted 2011-07-05 12:00:24 »

What exactly isn't OO about it?

Cas Smiley

Offline Roquen
« Reply #89 - Posted 2011-07-05 13:33:42 »

Is the question structs or Java?
Pages: 1 2 [3] 4 5 ... 7
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

toopeicgaming1999 (64 views)
2014-11-26 15:22:04

toopeicgaming1999 (57 views)
2014-11-26 15:20:36

toopeicgaming1999 (10 views)
2014-11-26 15:20:08

SHC (24 views)
2014-11-25 12:00:59

SHC (24 views)
2014-11-25 11:53:45

Norakomi (28 views)
2014-11-25 11:26:43

Gibbo3771 (24 views)
2014-11-24 19:59:16

trollwarrior1 (37 views)
2014-11-22 12:13:56

xFryIx (76 views)
2014-11-13 12:34:49

digdugdiggy (52 views)
2014-11-12 21:11:50
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!