peter-lawrey / HugeCollections-OLD

Huge Collections for Java using efficient off heap storage
273 stars 51 forks source link

support for "read through" and "write behind" gettr/settrs (in addition to JBI) #29

Closed Frank-Bradley closed 10 years ago

Cotton-Ben commented 10 years ago

Musing Openly: could there be any value to OpenHFT generating "read through" and "write behing" impl capabilty (from the standard JBI user provided interface)? In may be useful as it could deliver to the user an easier API for crossing read/write barrier(s) across PIDs?

e.g. where before my use of a spin-busy wait loop coded as

//Left PingPong Player
double _coupon = 4.0;
bondOffHeap.setCoupon(_coupon);  // won't cross write barrier to /dev/shm
while (_coupon == 4.0) {
       _coupon = bondOffHeap.getCoupon();  // won't cross read barrier to /dev/shm
}

left me without the effect I was seeking (I needed to do CASCoupon()), If OpenHFT could have taken my JBI (now with addl signatures for ' read through ' and 'write behind ) -- and generated an appropriate impl via the Runtime-Compiler, maybe my ambition to code a new spin-busy wait loop as follows could be OpenHFT supported:

//Left PingPong Player
double _coupon = 4.0;
bondOffHeap.setWriteBehindCoupon(_coupon);  // will cross write barrier to /dev/shm
while (_coupon == 4.0) {
       _coupon = bondOffHeap.getReadThroughCoupon();  // will cross read barrier to /dev/shm
}

Again, just musing openly. Using CAS works perfectly ... I'm just thinking of something that may be super simple to code from a user API view.

Frank-Bradley commented 10 years ago

@Cotton-Ben sorry about that. My cut-n-paste reply to this issue failed. I meant to say "+1"

peter-lawrey commented 10 years ago

We could support volatile read and write, (the underlying library does) however I think using a lock or CAS is safer.

If there is a really good use case for this, we could add it.

On 4 June 2014 16:43, Frank-Bradley notifications@github.com wrote:

Musing Openly: could there be any value to OpenHFT generating "read through" and "write behing" impl capabilty (from the standard JBI user provided interface)? In may be useful as it could deliver to the user an easier API for crossing read/write barrier(s) across PIDs?

e.g. where before my use of a spin-busy wait loop coded as

//Left PingPong Player double _coupon = 4.0; bondOffHeap.setCoupon(_coupon); // won't cross write barrier to /dev/shm while (_coupon == 4.0) { _coupon == bondOffHeap.getCoupon(); // won't cross read barrier to /dev/shm }

left me without the effect I was seeking (I needed to do CASCoupon()), If OpenHFT could have taken my JBI (now with addl signatures for ' read through ' and 'write behind ) -- and generated an appropriate impl via the Runtime-Compiler, maybe my ambition to code a new spin-busy wait loop as follows could be OpenHFT supported:

//Left PingPong Player double _coupon = 4.0; bondOffHeap.setWriteBehindCoupon(_coupon); // will cross write barrier to /dev/shm while (_coupon == 4.0) { _coupon == bondOffHeap.getReadThroughCoupon(); // will cross read barrier to /dev/shm }

Again, just musing openly. Using CAS works perfectly ... I'm just thinking of something that may be super simple to code from a user API view.

— Reply to this email directly or view it on GitHub https://github.com/OpenHFT/HugeCollections/issues/29.

Cotton-Ben commented 10 years ago

@peter-lawrey : That would be awesome from the vantage point of delivering a super simple user API view. IMHO the use of CAS-like capability and API is a little more awkard than interacting with very familiar volatile-like capability. Again, coding CAS-like is perfectly usable and solves the problem, I'm just musing openly.

Actually, Peter, I'm starting to really like the idea of you guys supporting volatile read/write in co-ordination with the JBI generated run-time impl. It would be easy to code (for the masses).

Cotton-Ben commented 10 years ago

If there is a really good use case for this, we could add it.

With all due respect to using a lock or CAS, I hope you might agree that empowering the user to code like this is a "really good" use case:

//Left PingPong Player
double _coupon = 4.0;
bondOffHeap.setWriteBehindCoupon(_coupon);  // will cross write barrier to /dev/shm
while (_coupon == 4.0) {
       _coupon = bondOffHeap.getReadThroughCoupon();  // will cross read barrier to /dev/shm
}
peter-lawrey commented 10 years ago

Using volatile is full of pit-falls. The problem with volatile is you can't use multiple operations in a safe manner but it can look like it works 99.9% of the time.

e.g. you can't do a

without the risk of a race condition.

If you have just one writing thread, you don't want to have multiple volatile writes to the same object. You only want the last write to be volatile. There is lots of issues to worry about to trip over a developer.

On 4 June 2014 16:58, Ben Cotton notifications@github.com wrote:

@peter-lawrey https://github.com/peter-lawrey : That would be awesome from the vantage point of delivering a super simple user API view. IMHO the use of CAS-like capability and API is a little more awkard than interacting with very familiar volatile-like capability. Again, coding CAS-like is perfectly usable and solves the problem, I'm just musing openly.

Actually, Peter, I'm starting to really like the idea of you guys supporting volatile read/write in co-ordination with the JBI generated run-time impl. It would be easy to code (for the masses).

— Reply to this email directly or view it on GitHub https://github.com/OpenHFT/HugeCollections/issues/29#issuecomment-45157394 .

Cotton-Ben commented 10 years ago

There is lots of issues to worry about to trip over a developer.

Forget it then! :)

Frank-Bradley commented 10 years ago

Could OpenHFT it be possible for the user to specify an interface that

bondOffHeap.setWriteBehindCoupon(_coupon); // will cross write barrier to /dev/shm _coupon = bondOffHeap.getReadThroughCoupon(); // will cross read barrier to /dev/shm

to be coded, but which was implemented by OpenHFT with something other than volatile?

The readThroughXXX() and writeBehindXXX() API being suggested seems like it would be helpful.

Cotton-Ben commented 10 years ago

Forget it then!

Wait. I think I am changing my mind (again). I just can't yet abandon this musing: Having an OpenHFT supported generation of readThroughXXX() and writeBehingXXX() impls that could enable a super-simple user API to cross read/write barriers to /dev/shm would indeed be very helpful. If it is at all do-able (without developer pitfals if done with volatile) then it would be very much welcomed here.

geminigx commented 10 years ago

Hi Peter, I also agree that coding via getReadThroughCoupon(); and setWriteBehindCoupon(); would be easier api then using compareAndSwapCoupon();.

Adding to the api the way Ben suggests allows each PID the option to either get the coupon from /dev/shm/SharedHashMap or from its local on heap reference.

Do you agree?

Thanks -Xiao

Cotton-Ben commented 10 years ago

What I think we need are 3 things:

  1. compareAndSwapCoupon(); // giving us Atomic {readThrough; writeBehind} order causality
  2. getReadThroughCoupon(); // single operation Read that for multi-pid crosses IPC r/w barriers
  3. setWriteBehindCoupon(); // single operattion Write that for multi-pid crosses IPC r/w barriers

2 and 3 are needed in addition to the default JBI getCoupon()/setCoupon() // default do not cross IPC r/w barriers

peter-lawrey commented 10 years ago

To be consistent, it would be

getVolatileCoupon()

setOrderedCoupon();

These would provide the best performance for these memory barrier-ed operations.

On 6 June 2014 01:17, Ben Cotton notifications@github.com wrote:

What I think we need are 3 things:

1.

compareAndSwapCoupon(); // giving us Atomic {readThrough; writeBehind} order causality 2.

getReadThroughCoupon(); // single operation Read that for multi-pid crosses IPC r/w barriers 3.

setWriteBehindCoupon(); // single operattion Write that for multi-pid crosses IPC r/w barriers

2 and 3 are needed in addition to the default JBI getCoupon()/setCoupon() // default do not cross IPC r/w barriers

— Reply to this email directly or view it on GitHub https://github.com/OpenHFT/HugeCollections/issues/29#issuecomment-45306198 .

geminigx commented 10 years ago

Hi Peter,

I think this will be a very good addition. OpenHFT providing support for our using both getVolatileCoupon() and setOrderedCoupon() will allow us to pass r/w barrier to /dev/shm for single operation use cases. If we need to do atomic multi-operation on coupon then absoluately we will use CAS.

Thanks! -Xiao

Cotton-Ben commented 10 years ago

getVolatileCoupon()

setOrderedCoupon();

@peter-lawrey Very nice. Thank you!

@geminigx +1 (emphatically)

RobAustin commented 10 years ago

Internal Jira raised JLANG-27 to add volatile getters and ordered writes to code generation so closing this issue.

danielshaya commented 10 years ago

Hi guys,

I've implemented this functionality which should now be available on GitHub.

There's a new test VolatileTest https://github.com/OpenHFT/Java-Lang/blob/master/lang/src/test/java/net/openhft/lang/model/VolatileTest.java where you can see the functionality in practice.

In short you need to match

getVolatileXXX()

with

setOrderedXXX()

Works both on and off heap and as well as with arrays.

Please let me have any feedback.

Regards Daniel

On Fri, Jun 6, 2014 at 4:37 PM, Ben Cotton notifications@github.com wrote:

getVolatileCoupon()

setOrderedCoupon();

@peter-lawrey https://github.com/peter-lawrey Very nice. Thank you!

@geminigx https://github.com/geminigx +1 (emphatically)

— Reply to this email directly or view it on GitHub https://github.com/OpenHFT/HugeCollections/issues/29#issuecomment-45350739 .

peter-lawrey commented 10 years ago

Obvious companions for these methods are addAtomicXxxx and compareAndSwapXxxx

On 11 June 2014 13:37, danielshaya notifications@github.com wrote:

Hi guys,

I've implemented this functionality which should now be available on GitHub.

There's a new test VolatileTest < https://github.com/OpenHFT/Java-Lang/blob/master/lang/src/test/java/net/openhft/lang/model/VolatileTest.java>

where you can see the functionality in practice.

In short you need to match

getVolatileXXX()

with

setOrderedXXX()

Works both on and off heap and as well as with arrays.

Please let me have any feedback.

Regards Daniel

On Fri, Jun 6, 2014 at 4:37 PM, Ben Cotton notifications@github.com wrote:

getVolatileCoupon()

setOrderedCoupon();

@peter-lawrey https://github.com/peter-lawrey Very nice. Thank you!

@geminigx https://github.com/geminigx +1 (emphatically)

— Reply to this email directly or view it on GitHub < https://github.com/OpenHFT/HugeCollections/issues/29#issuecomment-45350739>

.

— Reply to this email directly or view it on GitHub https://github.com/OpenHFT/HugeCollections/issues/29#issuecomment-45735079 .

Cotton-Ben commented 10 years ago

nice work you guys. thanks!

danielshaya commented 10 years ago

Thanks Ben,

To be clear about one thing I just changed in the implementation:

If you want to have a field XXX there are 3 options:

getXXX() setXXX()

or

getVolatileXXX() setOrderedXXX()

or

getXXX() setXXX() getVolatileXXX() setOrderedXXX()

On Wed, Jun 11, 2014 at 5:57 PM, Ben Cotton notifications@github.com wrote:

nice work you guys. thanks!

— Reply to this email directly or view it on GitHub https://github.com/OpenHFT/HugeCollections/issues/29#issuecomment-45769061 .

Cotton-Ben commented 10 years ago

which is exactly ideal, Daniel. Thank you.

As was pointed out by Peter earier in this issue, I should not have the expecation for PID1,PID2 lock-free multiple operations on the off-heap volatile reference to preserve orderings ... however I should have the expectation for PID1, PID2 lock-free single operations to work as expected ...

ie. both getVolatileXXX() and setOrderedXXX() will cross r/w barrier to physical /dev/shm/SharedHashMap and -- for single ops -- will provide correct order from both PID1 and PID2 views.

Nicely done Daniel!

Thx, Ben

peter-lawrey commented 10 years ago

Volatile and ordered provide the same happens before and after guarentees that volatile reads and writes do. The ordered write is the same as the AtomicXxxx lazySet operation. It is faster than a volatile write. On 11/06/2014 7:47 PM, "Ben Cotton" notifications@github.com wrote:

which is exactly ideal, Daniel. Thank you.

As was pointed out by Peter earier in this issue, I should not have the expecation for PID1,PID2 lock-free multiple operations on the off-heap volatile reference to preserve orderings ... however I should have the expectation for PID1, PID2 lock-free single operations to work as expected ...

ie. both getVolatileXXX() and setOrderedXXX() will cross r/w barrier to physical /dev/sh/SharedHashMap and -- for single ops -- will provide correct order from both PID1 and PID2 views.

Nicely done Daniel!

Thx, Ben

— Reply to this email directly or view it on GitHub https://github.com/OpenHFT/HugeCollections/issues/29#issuecomment-45783083 .

Cotton-Ben commented 10 years ago

:-) perfect!

RobAustin commented 10 years ago

@Ben if it helps we can cut a release build for you ?

On 11 Jun 2014, at 20:51, Ben Cotton notifications@github.com wrote:

:-) perfect!

— Reply to this email directly or view it on GitHub.

RobAustin commented 10 years ago

@Ben - if it helps, we can cut a release build for you ?

On 11 Jun 2014, at 20:51, Ben Cotton notifications@github.com wrote:

:-) perfect!

— Reply to this email directly or view it on GitHub.

Cotton-Ben commented 10 years ago

Actually, that would be very nice ... I want to be able to demo to certain "jaded" audiences this specific capability (which is ferociously cool ... an intra-PID volatile capability being implemented is unmistakably impressive) ....