From cagatayk at acm.org Mon Nov 2 11:11:02 2009
From: cagatayk at acm.org (Cagatay Kavukcuoglu)
Date: Mon, 2 Nov 2009 11:11:02 -0500
Subject: [concurrency-interest] Blocking peek/await in LBQ
In-Reply-To: <4AEC3CEB.7010501@cs.oswego.edu>
References: <35b8f8000910282032p43f1e907n4a9d69e08e70e8e@mail.gmail.com>
<4AEC3CEB.7010501@cs.oswego.edu>
Message-ID: <35b8f8000911020811s204b49d0jffab1d0f61b48c6@mail.gmail.com>
On Sat, Oct 31, 2009 at 8:34 AM, Doug Lea
wrote:
> Cagatay Kavukcuoglu wrote:
>>
>> Hi,
>>
>> I realize this was discussed before
>>
>> (http://cs.oswego.edu/pipermail/concurrency-interest/2009-June/006229.html),
>> but I wanted to see if folks think whether there are other ways to get
>> equivalent functionality. My particular use case is implementing a
>> concurrent data structure that would allow the usual tuple space
>> operations like read (blocks until a matching element exists and
>> returns without removing), take (like read, except the element is
>> removed) and put, where multiple values can be "queued" while being
>> associated with a key. An "await" operation on LinkedBlockingQueue
>> would have simplified the implementation significantly; in fact, I'm
>> duplicating LBQ code and adding this myself at the moment. Is there a
>> way to do this idiomatically in j.u.c that does not involve having to
>> resort to code duplication?
>>
>
> Basically, this amounts to supporting a change notification
> scheme for the particular event of a collection (here, a queue)
> becoming non-empty.
>
> Our resistance to supplying such things stems from not wanting
> to get into the business of adding to each concurrent collection
> all the different state-change mechanics (listeners? callbacks?
> blocking waits?) that you could apply to all their possible events
> (non-empty? empty? too big? insertion or removal of particular
> elements?) ?(Other library folks are less stubborn about this.
> I think some Apache and Google collections have some support
> for some of these options.)
>
My personal opinion is that this is a niche feature that only becomes
useful for a small minority and it's okay if that minority has to jump
through hoops as long as *some* solution is feasible. I do appreciate
the simplicity of the concurrent collections in j.u.c.
> But the easy cases of doing this yourself are pretty
> easy. For example you could use a synchronized wrapper class
> around nearly any collection or queue, adding
> a notifyAll on any insertion, along with an await
> method along the lines of:
> ?while (q.isEmpty() == null) wait();
Thanks, this makes more sense than duplicating code for the blocking queue.
> Although, if the single lock you'd need here for the wait/notify
> becomes a serious scalability problem, you'd need a more
> complicated solution.
This probably will be a problem later on but I can live with the
limitations at the moment. I was experimenting with something along
the lines of a new synchronizer based on AQS that blocks readers until
a value is provided (this part is easy - a bit like data
flow/FutureTask) and can be reset (this part turns out to be hard) to
represent the queue head. This was my first attempt at using AQS and
lock-free primitives for coordination; it's fun to work on, but hard
to write and test for.
>
>
> -Doug
>
From sanne.grinovero at gmail.com Sat Nov 7 06:28:18 2009
From: sanne.grinovero at gmail.com (Sanne Grinovero)
Date: Sat, 7 Nov 2009 12:28:18 +0100
Subject: [concurrency-interest] Concurrent approximate LRU?
In-Reply-To:
References:
Message-ID: <50e5f6250911070328q60f8a639yc495d25a29acbdf0@mail.gmail.com>
Hi Bryan,
I don't know the details of the implementation but Infinispan is doing
something similar; it's LGPL, so you might want to have a look in the
sources or ask to in the forums: www.jboss.org/infinispan
It implements "ConcurrentHashMap" so it should be straight-forward to drop in.
Especially related to your use case: have a look at the Hibernate
second level cache implementation based on Infinispan.
Sanne
2009/10/21 Bryan Thompson :
> Hello,
>
> We have a database with many different backing stores all of which compete to buffer ram in a shared LRU cache policy. ?We have implemented this using an outer concurrent hash map providing indirection to a collection of inner hash maps (we use LinkedHashMap here for better performance on its iterator, but we do not use its ability to impose an LRU ordering because the order must be shared across all inner cache instances). ?The keys are Long's. ?The values are elements in a double-linked list. ?If there is an LRU eviction then the record is evicted from the inner hash map corresponding to the store. ?This spreads out the memory constraint across the backing stores based on access.
>
> The problem with this approach is that the double-linked list is not thread-safe so we have to obtain a lock when testing the cache put adding to the cache and hold it across that operation. ?This is about a 10% performance penalty involved.
>
> Unfortunately, the ConcurrentHashMap does not allow us to impose an access policy, or we could use a single ConcurrentHashMap instance and use the store's identifier and the Long address of the record as a composite key and all would be good.
>
> I am wondering if there is a way to maintain an approximate LRU ordering across the elements in these different caches?
>
> Thanks in advance,
>
> -bryan
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
From tim at peierls.net Sat Nov 7 08:04:49 2009
From: tim at peierls.net (Tim Peierls)
Date: Sat, 7 Nov 2009 08:04:49 -0500
Subject: [concurrency-interest] Concurrent approximate LRU?
In-Reply-To: <50e5f6250911070328q60f8a639yc495d25a29acbdf0@mail.gmail.com>
References:
<50e5f6250911070328q60f8a639yc495d25a29acbdf0@mail.gmail.com>
Message-ID: <63b4e4050911070504p2267caf8ua1df6185031fe5d2@mail.gmail.com>
On Sat, Nov 7, 2009 at 6:28 AM, Sanne Grinovero
wrote:
> I don't know the details of the implementation but Infinispan is
> doing something similar; ...
> It implements "ConcurrentHashMap" so it should be straight-forward to drop
> in.
>
Infinispan's Cache extends ConcurrentMap. (ConcurrentHashMap is
a concrete type.)
--tim
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From kevinb at google.com Sat Nov 7 12:44:24 2009
From: kevinb at google.com (Kevin Bourrillion)
Date: Sat, 7 Nov 2009 09:44:24 -0800
Subject: [concurrency-interest] Concurrent approximate LRU?
In-Reply-To: <63b4e4050911070504p2267caf8ua1df6185031fe5d2@mail.gmail.com>
References:
<50e5f6250911070328q60f8a639yc495d25a29acbdf0@mail.gmail.com>
<63b4e4050911070504p2267caf8ua1df6185031fe5d2@mail.gmail.com>
Message-ID: <108fcdeb0911070944m1e6fd08ew3bc5b1f979e09542@mail.gmail.com>
Also, we're working actively to add support for bounded caches to MapMaker:
http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/MapMaker.html
We are investigating a fuzzy-LRU strategy, as well as ClockPro, which
seems very promising so far:
http://www.usenix.org/events/usenix05/tech/general/full_papers/jiang/jiang_html/
This is a refinement of LIRS (it can help to read this one first, perhaps):
http://www.cse.ohio-state.edu/hpcs/WWW/HTML/publications/papers/TR-02-6.pdf
We'd love to hear any reactions to, or particularly experience with,
LIRS and ClockPro.
On Sat, Nov 7, 2009 at 5:04 AM, Tim Peierls wrote:
> On Sat, Nov 7, 2009 at 6:28 AM, Sanne Grinovero
> wrote:
>>
>> I don't know the details of the implementation but Infinispan is
>> doing?something similar; ...
>> It implements "ConcurrentHashMap" so it should be straight-forward to drop
>> in.
>
> Infinispan's Cache extends ConcurrentMap. ?(ConcurrentHashMap is
> a concrete type.)
> --tim
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
--
Kevin Bourrillion @ Google
internal: http://go/javalibraries
external: guava-libraries.googlecode.com
From bryan at systap.com Sat Nov 7 14:13:33 2009
From: bryan at systap.com (Bryan Thompson)
Date: Sat, 7 Nov 2009 13:13:33 -0600
Subject: [concurrency-interest] Concurrent approximate LRU?
In-Reply-To: <50e5f6250911070328q60f8a639yc495d25a29acbdf0@mail.gmail.com>
References:
<50e5f6250911070328q60f8a639yc495d25a29acbdf0@mail.gmail.com>
Message-ID:
Sanne & Tim,
I will look into this. Thanks for pointing it out. I've been meaning to checkout infinispan anyway. Given the resounding silence on the list, it occurs to me that this can probably be handled with a mixture of the ConcurrentLinkedList and the ConcurrentHashMap, but I have not yet explored this possibility. The LIRS policy looks quite interesting.
You can take a look at the project that I am working on, which is http://www.bigdata.com/blog. This is a horizontally scaled MVCC database architecture with a focus on semantic web database applications.
Thanks,
-bryan
> -----Original Message-----
> From: Sanne Grinovero [mailto:sanne.grinovero at gmail.com]
> Sent: Saturday, November 07, 2009 6:28 AM
> To: Bryan Thompson
> Cc: concurrency-interest at cs.oswego.edu
> Subject: Re: [concurrency-interest] Concurrent approximate LRU?
>
> Hi Bryan,
> I don't know the details of the implementation but Infinispan
> is doing something similar; it's LGPL, so you might want to
> have a look in the sources or ask to in the forums:
> www.jboss.org/infinispan It implements "ConcurrentHashMap" so
> it should be straight-forward to drop in.
> Especially related to your use case: have a look at the
> Hibernate second level cache implementation based on Infinispan.
>
> Sanne
>
> 2009/10/21 Bryan Thompson :
> > Hello,
> >
> > We have a database with many different backing stores all
> of which compete to buffer ram in a shared LRU cache policy. ?
> We have implemented this using an outer concurrent hash map
> providing indirection to a collection of inner hash maps (we
> use LinkedHashMap here for better performance on its
> iterator, but we do not use its ability to impose an LRU
> ordering because the order must be shared across all inner
> cache instances). ?The keys are Long's. ?The values are
> elements in a double-linked list. ?If there is an LRU
> eviction then the record is evicted from the inner hash map
> corresponding to the store. ?This spreads out the memory
> constraint across the backing stores based on access.
> >
> > The problem with this approach is that the double-linked
> list is not thread-safe so we have to obtain a lock when
> testing the cache put adding to the cache and hold it across
> that operation. ?This is about a 10% performance penalty involved.
> >
> > Unfortunately, the ConcurrentHashMap does not allow us to
> impose an access policy, or we could use a single
> ConcurrentHashMap instance and use the store's identifier and
> the Long address of the record as a composite key and all
> would be good.
> >
> > I am wondering if there is a way to maintain an approximate
> LRU ordering across the elements in these different caches?
> >
> > Thanks in advance,
> >
> > -bryan
> > _______________________________________________
> > Concurrency-interest mailing list
> > Concurrency-interest at cs.oswego.edu
> > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >
>
From michael.m.spiegel at gmail.com Sat Nov 7 15:01:07 2009
From: michael.m.spiegel at gmail.com (Michael Spiegel)
Date: Sat, 7 Nov 2009 15:01:07 -0500
Subject: [concurrency-interest] PriorityBlockingQueue put() operation
Message-ID: <1901f69e0911071201r4d85fe98lbd476450813c4a79@mail.gmail.com>
Hi,
I apologize if this question has been answered before of if the answer
is trivially obvious. The documentation for
java.util.concurrent.PriorityBlockingQueue states that the put(E e)
method will never block, and such claims are not made about the add(E
e) method. The method bodies for both methods are identical, ignoring
the fact that one method returns boolean and the other doesn't return
a value. The methods body is an invocation to the offer(E e) method.
I believe that offer() is a blocking method, since it locks the
ReentrantLock around the data structure. So is put() a blocking
method? I must be missing something obvious.
Thanks!
--Michael
From tim at peierls.net Sat Nov 7 15:45:46 2009
From: tim at peierls.net (Tim Peierls)
Date: Sat, 7 Nov 2009 15:45:46 -0500
Subject: [concurrency-interest] PriorityBlockingQueue put() operation
In-Reply-To: <1901f69e0911071201r4d85fe98lbd476450813c4a79@mail.gmail.com>
References: <1901f69e0911071201r4d85fe98lbd476450813c4a79@mail.gmail.com>
Message-ID: <63b4e4050911071245y50d81b06i3c5d89fd91708d4d@mail.gmail.com>
On Sat, Nov 7, 2009 at 3:01 PM, Michael Spiegel wrote:
> Hi,
>
> I apologize if this question has been answered before of if the answer
> is trivially obvious. The documentation for
> java.util.concurrent.PriorityBlockingQueue states that the put(E e)
> method will never block, and such claims are not made about the add(E
> e) method. The method bodies for both methods are identical, ignoring
> the fact that one method returns boolean and the other doesn't return
> a value. The methods body is an invocation to the offer(E e) method.
> I believe that offer() is a blocking method, since it locks the
> ReentrantLock around the data structure. So is put() a blocking
> method? I must be missing something obvious.
>
Simply holding a lock doesn't necessarily make a method into a blocking
method. A blocking method conventionally has "throws InterruptedException"
in its signature, a sign to calling code that the method might wait (i.e.,
block) until some condition holds, and that the caller should be prepared to
handle the possibility of interruption while it waits.
The add() method comes from java.util.Collection; it's not a blocking
method. The (untimed) offer() method comes from java.util.Queue; it isn't a
blocking method, either.
BlockingQueue.put() *is* generally a blocking method; it waits for the queue
to have room for the new element and throws InterruptedException if
interrupted while waiting. But since PriorityBlockingQueue is unbounded, it
always has room, so it never has to wait and there is no need for it to
throw InterruptedException. So PriorityBlockingQueue.put() is not a blocking
method.
--tim
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From martinrb at google.com Sat Nov 7 15:48:48 2009
From: martinrb at google.com (Martin Buchholz)
Date: Sat, 7 Nov 2009 12:48:48 -0800
Subject: [concurrency-interest] PriorityBlockingQueue put() operation
In-Reply-To: <1901f69e0911071201r4d85fe98lbd476450813c4a79@mail.gmail.com>
References: <1901f69e0911071201r4d85fe98lbd476450813c4a79@mail.gmail.com>
Message-ID: <1ccfd1c10911071248p2093c6c8ybad4b98afc1acc1c@mail.gmail.com>
There is a terminology problem here.
Since locks are used, none of the methods are "non-blocking"
in the currently popular technical sense.
I don't know how best to describe an algorithm that
will need to acquire a lock, but once it does so,
will be able to proceed immediately, and not have to
wait indefinitely for some other thread to take action.
The word "wait-free" is taken.
Martin
On Sat, Nov 7, 2009 at 12:01, Michael Spiegel
wrote:
> Hi,
>
> I apologize if this question has been answered before of if the answer
> is trivially obvious. The documentation for
> java.util.concurrent.PriorityBlockingQueue states that the put(E e)
> method will never block, and such claims are not made about the add(E
> e) method. The method bodies for both methods are identical, ignoring
> the fact that one method returns boolean and the other doesn't return
> a value. The methods body is an invocation to the offer(E e) method.
> I believe that offer() is a blocking method, since it locks the
> ReentrantLock around the data structure. So is put() a blocking
> method? I must be missing something obvious.
>
> Thanks!
> --Michael
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From tim at peierls.net Sat Nov 7 16:32:59 2009
From: tim at peierls.net (Tim Peierls)
Date: Sat, 7 Nov 2009 16:32:59 -0500
Subject: [concurrency-interest] PriorityBlockingQueue put() operation
In-Reply-To: <1ccfd1c10911071248p2093c6c8ybad4b98afc1acc1c@mail.gmail.com>
References: <1901f69e0911071201r4d85fe98lbd476450813c4a79@mail.gmail.com>
<1ccfd1c10911071248p2093c6c8ybad4b98afc1acc1c@mail.gmail.com>
Message-ID: <63b4e4050911071332g2ae48869ocbb2dee95e8df957@mail.gmail.com>
On Sat, Nov 7, 2009 at 3:48 PM, Martin Buchholz wrote:
> There is a terminology problem here.
> Since locks are used, none of the methods are "non-blocking"
> in the currently popular technical sense.
>
True, but I think the term "blocking method" is more usefully (if sloppily)
applied only to "throws IE" situations.
> I don't know how best to describe an algorithm that
> will need to acquire a lock, but once it does so,
> will be able to proceed immediately, and not have to
> wait indefinitely for some other thread to take action.
> The word "wait-free" is taken.
>
"Effectively non-blocking"? "Contentious"? :-)
This is not a distinction I'd want to force on people who just want to use
j.u.c types without becoming concurrency experts.
--tim
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From joe.bowbeer at gmail.com Sat Nov 7 18:00:44 2009
From: joe.bowbeer at gmail.com (Joe Bowbeer)
Date: Sat, 7 Nov 2009 15:00:44 -0800
Subject: [concurrency-interest] PriorityBlockingQueue put() operation
In-Reply-To: <1901f69e0911071201r4d85fe98lbd476450813c4a79@mail.gmail.com>
References: <1901f69e0911071201r4d85fe98lbd476450813c4a79@mail.gmail.com>
Message-ID: <31f2a7bd0911071500m762ac6a6p8b869d617584ece4@mail.gmail.com>
On Sat, Nov 7, 2009 at 12:01 PM, Michael Spiegel wrote:
> Hi,
>
> I apologize if this question has been answered before of if the answer
> is trivially obvious. The documentation for
> java.util.concurrent.PriorityBlockingQueue states that the put(E e)
> method will never block, and such claims are not made about the add(E
> e) method. The method bodies for both methods are identical, ignoring
> the fact that one method returns boolean and the other doesn't return
> a value. The methods body is an invocation to the offer(E e) method.
> I believe that offer() is a blocking method, since it locks the
> ReentrantLock around the data structure. So is put() a blocking
> method? I must be missing something obvious.
>
> Thanks!
> --Michael
>
Wikipedia currently makes this distinction:
"In computer science, non-blocking synchronization ensures that threads
competing for a shared resource do not have their execution indefinitely
postponed by mutual exclusion. A non-blocking algorithm is lock-free if
there is guaranteed system-wide progress; wait-free if there is also
guaranteed per-thread progress."
http://en.wikipedia.org/wiki/Non-blocking_synchronization
So non-blocking < lock-free < wait-free ?
Consider old (blocking) java.io and the newer asynchronous java.nio. They
both use locks of some sort, but nio is non-blocking.
Object.wait is typically a good indicator of blocking. (As is throws IE.)
--Joe
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From davidcholmes at aapt.net.au Sat Nov 7 18:12:33 2009
From: davidcholmes at aapt.net.au (David Holmes)
Date: Sun, 8 Nov 2009 09:12:33 +1000
Subject: [concurrency-interest] PriorityBlockingQueue put() operation
In-Reply-To: <31f2a7bd0911071500m762ac6a6p8b869d617584ece4@mail.gmail.com>
Message-ID:
The term non-blocking here (BlockingQueue.put) is being used in a different
sense to that of the non-blocking/wait-free/lock-free algorithms. It is an
unfortunate terminology clash but the lock-free/wait-free/non-blocking
terminology is only considering mutual-exclusion/atomicity related blocking
(for want of a better term).
In general any method that has to wait for a state-related condition to hold
(space in buffer, item in buffer, data on socket, time-X-has-elapsed) is a
blocking method, and any method that doesn't have to wait is a non-blocking
method. And this is independent of whether locking is also involved.
David
-----Original Message-----
From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Joe Bowbeer
Sent: Sunday, 8 November 2009 9:01 AM
To: concurrency-interest at cs.oswego.edu
Subject: Re: [concurrency-interest] PriorityBlockingQueue put() operation
On Sat, Nov 7, 2009 at 12:01 PM, Michael Spiegel wrote:
Hi,
I apologize if this question has been answered before of if the answer
is trivially obvious. The documentation for
java.util.concurrent.PriorityBlockingQueue states that the put(E e)
method will never block, and such claims are not made about the add(E
e) method. The method bodies for both methods are identical, ignoring
the fact that one method returns boolean and the other doesn't return
a value. The methods body is an invocation to the offer(E e) method.
I believe that offer() is a blocking method, since it locks the
ReentrantLock around the data structure. So is put() a blocking
method? I must be missing something obvious.
Thanks!
--Michael
Wikipedia currently makes this distinction:
"In computer science, non-blocking synchronization ensures that threads
competing for a shared resource do not have their execution indefinitely
postponed by mutual exclusion. A non-blocking algorithm is lock-free if
there is guaranteed system-wide progress; wait-free if there is also
guaranteed per-thread progress."
http://en.wikipedia.org/wiki/Non-blocking_synchronization
So non-blocking < lock-free < wait-free ?
Consider old (blocking) java.io and the newer asynchronous java.nio. They
both use locks of some sort, but nio is non-blocking.
Object.wait is typically a good indicator of blocking. (As is throws
IE.)
--Joe
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From martinrb at google.com Sat Nov 7 23:37:32 2009
From: martinrb at google.com (Martin Buchholz)
Date: Sat, 7 Nov 2009 20:37:32 -0800
Subject: [concurrency-interest] PriorityBlockingQueue put() operation
In-Reply-To: <31f2a7bd0911071500m762ac6a6p8b869d617584ece4@mail.gmail.com>
References: <1901f69e0911071201r4d85fe98lbd476450813c4a79@mail.gmail.com>
<31f2a7bd0911071500m762ac6a6p8b869d617584ece4@mail.gmail.com>
Message-ID: <1ccfd1c10911072037h488c72a8v38bb68cce3d36073@mail.gmail.com>
On Sat, Nov 7, 2009 at 15:00, Joe Bowbeer wrote:
>
> Wikipedia currently makes this distinction:
>
> "In computer science, non-blocking synchronization ensures that threads
> competing for a shared resource do not have their execution indefinitely
> postponed by mutual exclusion. A non-blocking algorithm is lock-free if
> there is guaranteed system-wide progress; wait-free if there is also
> guaranteed per-thread progress."
>
> http://en.wikipedia.org/wiki/Non-blocking_synchronization
>
> So non-blocking < lock-free < wait-free ?
>
>
I read it a little differently.
"lock-free" is a kind of "non-blocking synchronization",
the weakest kind. So:
non-blocking <= lock-free < wait-free
non-blocking synchronization cannot involve locks,
since some thread can acquire the lock and never be scheduled again,
causing *all* threads to
"have their execution indefinitely postponed by mutual exclusion".
Martin
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From Mark.Moir at Sun.COM Sun Nov 8 21:25:02 2009
From: Mark.Moir at Sun.COM (Mark Moir)
Date: Sun, 08 Nov 2009 21:25:02 -0500
Subject: [concurrency-interest] Concurrency-interest Digest, Vol 58,
Issue 5
In-Reply-To:
References:
Message-ID: <4AF77D7E.4000103@sun.com>
> From: Martin Buchholz
> Subject: Re: [concurrency-interest] PriorityBlockingQueue put()
> operation
> To: Joe Bowbeer
> Cc: "concurrency-interest at cs.oswego.edu"
>
> Message-ID:
> <1ccfd1c10911072037h488c72a8v38bb68cce3d36073 at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
>
> On Sat, Nov 7, 2009 at 15:00, Joe Bowbeer wrote:
>
>> Wikipedia currently makes this distinction:
>>
>> "In computer science, non-blocking synchronization ensures that threads
>> competing for a shared resource do not have their execution indefinitely
>> postponed by mutual exclusion. A non-blocking algorithm is lock-free if
>> there is guaranteed system-wide progress; wait-free if there is also
>> guaranteed per-thread progress."
>>
>> http://en.wikipedia.org/wiki/Non-blocking_synchronization
>>
>> So non-blocking < lock-free < wait-free ?
>>
>>
> I read it a little differently.
> "lock-free" is a kind of "non-blocking synchronization",
> the weakest kind. So:
> non-blocking <= lock-free < wait-free
>
> non-blocking synchronization cannot involve locks,
> since some thread can acquire the lock and never be scheduled again,
> causing *all* threads to
> "have their execution indefinitely postponed by mutual exclusion".
David is right that these terms are overloaded and that the use here
is not related to the obstruction-free/lock-free/wait-free meaning of
non-blocking. It would probably be useful to make this distinction in
a clear and consistent way in the documentation.
The Wikipedia entry (have we really got to the point of citing
Wikipedia? :-)) is sort of right in spirit, but is not precise enough
to be meaningful, and is somewhat misleading. In particular, it is
possible to have blocking behavior without having mutual exclusion.
Furthermore, there are unstated assumptions about the system and
system mode. For example, a lock-free algorithm does not guarantee
system-wide progress. What it guarantees is that *if* some thread
takes infinitely many steps attempting to complete an operation,
*then* infinitely many operations complete. If the scheduler decides
not to run any threads, then no progress will be made, but that does
not mean the algorithm is not lock-free.
Also, a lock-free algorithm must make the guarantee it makes in a
fully asynchronous execution model, in which the algorithm cannot make
assumptions about the relative execution speed of different threads,
cannot make fairness assumptions, cannot assume any thread will take
another step, etc. (Similarly for obstruction-free and wait-free.)
Finally, it is not true that lock-freedom is the weakest form of
non-blocking progress condition. Obstruction-freedom is weaker: it
guarantees progress to an operation *only* if it eventually executes
in isolation. A lock-free algorithm guarantees that if (exactly) two
operations continually take steps in completing an operation, one of
the will eventually complete. Obstruction-freedom does not guarantee
that.
I have often thought of obstruction-freedom as "the weakest
non-blocking progress condition" and in a deterministic system, I
think that is true. But others have pointed out that in a
probabilistic model, you can have an algorithm that guarantees
completion in isolation with high probability, but not
deterministically. Whether you still consider such a thing to be
non-blocking is up to you :-) .
I hope this is helpful.
Cheers
Mark
From dvyukov at gmail.com Tue Nov 10 05:57:42 2009
From: dvyukov at gmail.com (Dmitriy V'jukov)
Date: Tue, 10 Nov 2009 13:57:42 +0300
Subject: [concurrency-interest] Fences APIand visibility/coherency
In-Reply-To: <238A96A773B3934685A7269CC8A8D042577D6AD21C@GVW0436EXB.americas.hpqcorp.net>
References: <9014da950910160528l15ea68dsa419bf34965a3e03@mail.gmail.com>
<238A96A773B3934685A7269CC8A8D042577D6AD21C@GVW0436EXB.americas.hpqcorp.net>
Message-ID: <9014da950911100257o537e2cb0qceb5c9bb721fbdcb@mail.gmail.com>
On Sat, Oct 17, 2009 at 3:46 AM, Boehm, Hans wrote:
>
>
> > -----Original Message-----
> > From: Dmitriy V'jukov [mailto:dvyukov at gmail.com]
> > Sent: Friday, October 16, 2009 5:28 AM
> > To: concurrency-interest at cs.oswego.edu;
> > javamemorymodel-discussion at cs.umd.edu
> > Cc: Doug Lea; Boehm, Hans; davidcholmes at aapt.net.au; Adam Morrison
> > Subject: Fences APIand visibility/coherency
> >
> > > Date: Thu, 15 Oct 2009 18:18:48 +0000
> > > From: "Boehm, Hans"
> > > Subject: Re: [concurrency-interest] [Javamemorymodel-discussion]
> > > Fences APIand visibility/coherency
> >
> > > I'm not sure we have a real disagreement here about how
> > implementations should behave. But I think we're running
> > into a limitation of language specifications in general:
> > They can only specify the allowable behavior of a program,
> > not the details of the implementation. Once we agree that
> > our example program is allowed not to terminate (because we
> > want to allow dumb schedulers), the implementation is allowed
> > to produce that nonterminating behavior in any way it wants.
> >
> > Hans,
> >
> > I understand what you are talking about, and this makes
> > sense. However here is some thoughts on this.
> >
> > Is it why "synchronization order must be a countable set"
> > removed in favor of "Java does not require fair scheduler"
> > (providing both statements is contradicting)?
> As I said in my last message, I don't think the intent was to remove it,
> just to restate it. See the section on observable behavior.
> >
> > As far as I understand, what you are saying effectively
> > implying that volatile and plain vars are basically the same
> > (ordering aside). I.e.
> > assume I am in your team and write "signaling on a flag" with
> > flag declared as plain var. You say to me: Hey, Dmitry, you
> > have to declare flag as volatile. Me: But why, Hans? They
> > both may work, and neither guaranteed to work. So what's the
> > distinction? What will you answer to me?
> The volatile flag will guarantee partial correctness; If you see the flag
> set, you will see prior state updates by the thread setting the flag. The
> ordinary variable one won't guarantee that.
>
> As a practical matter, the volatile flag will work as far as termination
> properties are concerned, the other one may well not. I believe the
> volatile flag is guaranteed to do the right thing for applications that work
> no matter what the scheduler does.
>
Hi Hans, concurrency-interest, javamemorymodel-discussion,
Sorry for delay, it took some time to form consistent reasoning on the
topic. Here is how I understand the problem now.
JLS does not provide strict guarantees regarding propagation of changes
between threads. So most Java programs have to rely on quality and sanity of
language implementation. But it's Ok, because they most likely do it anyway.
There are 1000 and 1 way how "bad" language implementation can break
reasonable programs while staying 100% conforming. For example,
implementation can allow allocation of at most 4 bytes of dynamic memory, or
give zero stack space, or allow creation of at most 1 thread, or make every
volatile assignment (or any other operation) take 10^10 years of wall clock
time (i.e. visible hang of all programs, even single-threaded), etc, etc.
Language standard can't specify exactly how much dynamic memory
implementation must guarantee, however we all understand that implementation
will do it's best to provide as much dynamic memory as possible. "Good"
language implementation handles everything in a best-effort way,
particularly it tries to make volatile stores visible to other threads as
soon as possible.
So the only formal guarantee that makes sense in such an environment is -
program must work correctly or does not work at all. And that's what
guaranteed for volatiles.
Hope I get it in the right way now.
p.s. I still see some possible practical problem with Fences.orderWrites()
because it relies on plain store, so I do not quite see why even "good"
language implementation will prevent it from sinking below an infinite loop
or something like that. Is it intended that compiler must specifically
handle assignment after an Fences.orderWrites()?
I would expect ordering of writes and the store be combined into a single
operation, so that compiler will be able to ensure correct code generation.
I.e.orderReads(O) actually means getAndOrderReads(O), i.e. the load is a
part of the operations. This allows an implementation to emit actual load
from main memory and prevent all reorderings on compiler level. This is
enough to ensure useful guarantees. In order to be consistent,
orderWrites(O) must have a form of orderWritesAndSet(X, O), so that the
store is a part of the operation. This will allow an implementation to emit
actual write to main memory and prevent all reorderings on compiler level.
As a side effect such form will be consistent with C++0x's
std::atomic::store(memory_order_release), and C#'s Thread.VolatileWrite().
--
Dmitriy V'jukov
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From dl at cs.oswego.edu Sun Nov 15 09:10:38 2009
From: dl at cs.oswego.edu (Doug Lea)
Date: Sun, 15 Nov 2009 09:10:38 -0500
Subject: [concurrency-interest] jsr166y classes now in jdk7m5
Message-ID: <4B000BDE.1080802@cs.oswego.edu>
ForkJoin, Phasers, and TransferQueues are now incorporated
in package java.util.concurrent in the latest JDK7 snapshots,
downloadable at http://download.java.net/jdk7/m5/
Please try these out and let us know of any problems.
We will still maintain JDK6-compatible versions
for the indefinite future in package jsr166y (see
http://gee.cs.oswego.edu/dl/concurrency-interest/index.html)
This should also make it easier for those using these
classes from other languages and frameworks. You can
rely on jsr166y versions until JDK7 release, although at
that point you'll probably need to make a visible
switch-over to j.u.c versions. Further, it is likely
that at some point we will make changes that
rely on other JDK7 features.
Especially during this transition, please be careful
with "import" statements in sources --
avoiding "*" imports from either jsr166y or
java.util.concurrent, to avoid compile-time
or run-time errors about name clashes by users
running JDK7 snapshots.
In general, changes show up in our jsr166y
and j.u.c CVS before they appear in openjdk or
Sun JDK7 snapshot releases.
There already a few small improvements there vs
jdk7m5 versions. We plan to occasionally commit
small batches of them into openjdk.
We don't have plans for JDK5 backports. There
are a couple of performance-critical constructions
in these classes that rely on JDK6 intrinsics.
They are costly to emulate in JDK5, so it is
not clear how useful they would be.
This also impacts current IBM Java (J9) users even in
JDK6, because it doesn't support some of the
hotspot intrinsics. I understand that this will
be addressed in an IBM JDK6 update.
More generally, we are hoping to find a way to
ensure compatibility in the future across JVMs for
these JDK-internal non-public APIs (that have
escaped standardization), to avoid future problems
along these lines.
The main known remaining jsr166-related task for JDK7 is
to try to make good on schemes that avoid the need
for the controversial Fences API by improving
AtomicXUpdater APIs and somehow removing their overhead.
-Doug
From alexdmiller at yahoo.com Sun Nov 15 15:26:08 2009
From: alexdmiller at yahoo.com (Alex Miller)
Date: Sun, 15 Nov 2009 12:26:08 -0800 (PST)
Subject: [concurrency-interest] jsr166y classes now in jdk7m5
In-Reply-To:
References:
Message-ID: <554927.5702.qm@web32205.mail.mud.yahoo.com>
Glad to see stuff hitting the JDK 7 repo. I'm guessing from this message that stuff like ConcurrentReferenceHashMap / MapMaker or the concurrent LRU work won't make it into JDK 7?
Alex
----- Original Message ----
> From: "concurrency-interest-request at cs.oswego.edu"
> To: concurrency-interest at cs.oswego.edu
> Sent: Sun, November 15, 2009 11:00:00 AM
> Subject: Concurrency-interest Digest, Vol 58, Issue 8
>
> Send Concurrency-interest mailing list submissions to
> concurrency-interest at cs.oswego.edu
>
> To subscribe or unsubscribe via the World Wide Web, visit
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> or, via email, send a message with subject or body 'help' to
> concurrency-interest-request at cs.oswego.edu
>
> You can reach the person managing the list at
> concurrency-interest-owner at cs.oswego.edu
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Concurrency-interest digest..."
>
>
> Today's Topics:
>
> 1. jsr166y classes now in jdk7m5 (Doug Lea)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Sun, 15 Nov 2009 09:10:38 -0500
> From: Doug Lea
> Subject: [concurrency-interest] jsr166y classes now in jdk7m5
> To: "concurrency-interest at cs.oswego.edu"
>
> Message-ID: <4B000BDE.1080802 at cs.oswego.edu>
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
> ForkJoin, Phasers, and TransferQueues are now incorporated
> in package java.util.concurrent in the latest JDK7 snapshots,
> downloadable at http://download.java.net/jdk7/m5/
>
> Please try these out and let us know of any problems.
>
> We will still maintain JDK6-compatible versions
> for the indefinite future in package jsr166y (see
> http://gee.cs.oswego.edu/dl/concurrency-interest/index.html)
> This should also make it easier for those using these
> classes from other languages and frameworks. You can
> rely on jsr166y versions until JDK7 release, although at
> that point you'll probably need to make a visible
> switch-over to j.u.c versions. Further, it is likely
> that at some point we will make changes that
> rely on other JDK7 features.
>
> Especially during this transition, please be careful
> with "import" statements in sources --
> avoiding "*" imports from either jsr166y or
> java.util.concurrent, to avoid compile-time
> or run-time errors about name clashes by users
> running JDK7 snapshots.
>
> In general, changes show up in our jsr166y
> and j.u.c CVS before they appear in openjdk or
> Sun JDK7 snapshot releases.
> There already a few small improvements there vs
> jdk7m5 versions. We plan to occasionally commit
> small batches of them into openjdk.
>
> We don't have plans for JDK5 backports. There
> are a couple of performance-critical constructions
> in these classes that rely on JDK6 intrinsics.
> They are costly to emulate in JDK5, so it is
> not clear how useful they would be.
> This also impacts current IBM Java (J9) users even in
> JDK6, because it doesn't support some of the
> hotspot intrinsics. I understand that this will
> be addressed in an IBM JDK6 update.
> More generally, we are hoping to find a way to
> ensure compatibility in the future across JVMs for
> these JDK-internal non-public APIs (that have
> escaped standardization), to avoid future problems
> along these lines.
>
> The main known remaining jsr166-related task for JDK7 is
> to try to make good on schemes that avoid the need
> for the controversial Fences API by improving
> AtomicXUpdater APIs and somehow removing their overhead.
>
> -Doug
>
>
>
>
>
> ------------------------------
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
> End of Concurrency-interest Digest, Vol 58, Issue 8
> ***************************************************
From dl at cs.oswego.edu Sun Nov 15 16:51:43 2009
From: dl at cs.oswego.edu (Doug Lea)
Date: Sun, 15 Nov 2009 16:51:43 -0500
Subject: [concurrency-interest] jsr166y classes now in jdk7m5
In-Reply-To: <554927.5702.qm@web32205.mail.mud.yahoo.com>
References:
<554927.5702.qm@web32205.mail.mud.yahoo.com>
Message-ID: <4B0077EF.1050808@cs.oswego.edu>
Alex Miller wrote:
> I'm guessing from this message
> that stuff like ConcurrentReferenceHashMap / MapMaker or the concurrent LRU
> work won't make it into JDK 7?
>
Hard to say, since we don't know how far out Java7/JDK7 will
be. The two main concerns are:
* Most caches would benefit from dependent weak reference
(aka ephemeron) JVM support, which is not currently planned.
* I don't think we have much consensus yet on which replacement
policies (pseudo-LRU etc) are amenable to standardized
library support and/or how to allow plugging in more
specialized forms like those that Bob Lee, Kevin Bourrillion,
and friends have been working on for Google collections.
In some analogous situations, we've settled on
the idea that providing something is better than nothing.
But in this case just putting out something hits various
API design controversies, like should a "cached function"
act more like a Map or a Function. Oh, wait, we don't
even have a Function API and may never want/need one if
Java ever supports function-types. And several more along
these lines. So for the time being I'm hoping that
people will be content to continue to use pre-standardized
cache components out there until some of these various JVM,
algorithmic, and API issues become better resolved.
-Doug
From dl at cs.oswego.edu Sun Nov 15 17:37:39 2009
From: dl at cs.oswego.edu (Doug Lea)
Date: Sun, 15 Nov 2009 17:37:39 -0500
Subject: [concurrency-interest] ParallelArrays via Relooper
Message-ID: <4B0082B3.6000200@cs.oswego.edu>
Continuing some overdue notes related to what will,
might, and won't ship in JDK7...
We aren't currently planning to release
extra166y.ParallelArray and friends as part of JKD7,
although they will continue to be available and hopefully
improved, and possibly extended with Map (vs Array) support.
People who would like to use ForkJoin processing in
higher-level constructions than supported at the plain
ForkJoinTask level might be interested in the Relooper
tool by Danny Dig and friends at University of Illinois. See
https://netfiles.uiuc.edu/dig/RefactoringInfo/tools/ReLooper/
This is an Eclipse-based refactoring tool that helps
automate creation of some ParallelArray constructions,
including automated definition of various little
function-objects etc. (The need for which is (only one)
of the reasons for not including ParallelArray in JDK7).
Relooper also guides choices among aggregate operations.
I was very impressed when Danny demoed it
a few weeks ago at OOPSLA. Some of the sample
refactored programs are realistic enough
that I expect it will be useful to just about anyone
interested in exploring these forms of parallelization.
(There are also existing or planned frameworks in
other languages that run on JVMs for parallel
aggregate (i.e., array, collection, and/or map)
operations that might rely on ParallelArray etc
or variants of them.)
-Doug
From martinrb at google.com Sun Nov 15 21:14:01 2009
From: martinrb at google.com (Martin Buchholz)
Date: Sun, 15 Nov 2009 18:14:01 -0800
Subject: [concurrency-interest] jsr166y classes now in jdk7m5
In-Reply-To: <4B0077EF.1050808@cs.oswego.edu>
References:
<554927.5702.qm@web32205.mail.mud.yahoo.com>
<4B0077EF.1050808@cs.oswego.edu>
Message-ID: <1ccfd1c10911151814u32ab9ea6t2333b8cc1d44a6dd@mail.gmail.com>
On Sun, Nov 15, 2009 at 13:51, Doug Lea wrote:
> Alex Miller wrote:
>
>> I'm guessing from this message
>> that stuff like ConcurrentReferenceHashMap / MapMaker or the concurrent
>> LRU
>> work won't make it into JDK 7?
>>
>>
> * I don't think we have much consensus yet on which replacement
> policies (pseudo-LRU etc) are amenable to standardized
> library support and/or how to allow plugging in more
> specialized forms like those that Bob Lee, Kevin Bourrillion,
> and friends have been working on for Google collections.
>
Caching is hard to get right, and the Google classes are still in
development.
There definitely will be solutions for everyone to use,
but they will be part of a third-party package from Google.
I agree with Doug that it seems too early to try to standardize them now.
Integrating them into JDK8 seems more realistic.
Martin
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From alexdmiller at yahoo.com Sun Nov 15 22:16:27 2009
From: alexdmiller at yahoo.com (Alex Miller)
Date: Sun, 15 Nov 2009 19:16:27 -0800 (PST)
Subject: [concurrency-interest] jsr166y classes now in jdk7m5
In-Reply-To: <1ccfd1c10911151814u32ab9ea6t2333b8cc1d44a6dd@mail.gmail.com>
References:
<554927.5702.qm@web32205.mail.mud.yahoo.com>
<4B0077EF.1050808@cs.oswego.edu>
<1ccfd1c10911151814u32ab9ea6t2333b8cc1d44a6dd@mail.gmail.com>
Message-ID: <612579.5731.qm@web32203.mail.mud.yahoo.com>
Makes sense to me. We've definitely felt the need for the CRHM stuff at Terracotta and usually have either used MapMaker or rolled our own. I'd love to have something like that in the JDK, but I know how these software things go...
It definitely seems challenging to me to build a concurrent LRU that is flexible enough to cover the range of common use cases while not turning it into a full-fledged cache ala Ehcache.
Alex
>
>From: Martin Buchholz
>To: Doug Lea
>Cc: Alex Miller ; concurrency-interest at cs.oswego.edu
>Sent: Sun, November 15, 2009 8:14:01 PM
>Subject: Re: [concurrency-interest] jsr166y classes now in jdk7m5
>
>
>
>
>On Sun, Nov 15, 2009 at 13:51, Doug Lea wrote:
>
>Alex Miller wrote:
>>
>>>>>I'm guessing from this message
>>>>>>that stuff like ConcurrentReferenceHashMap / MapMaker or the concurrent LRU
>>>>>>work won't make it into JDK 7?
>>>
>>>
>>
>>* I don't think we have much consensus yet on which replacement
>>>>policies (pseudo-LRU etc) are amenable to standardized
>>>>library support and/or how to allow plugging in more
>>>>specialized forms like those that Bob Lee, Kevin Bourrillion,
>>>>and friends have been working on for Google collections.
>>
>Caching is hard to get right, and the Google classes are still in development.
>There definitely will be solutions for everyone to use,
>>but they will be part of a third-party package from Google.
>I agree with Doug that it seems too early to try to standardize them now.
>Integrating them into JDK8 seems more realistic.
>
>Martin
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From crazybob at crazybob.org Mon Nov 16 11:07:10 2009
From: crazybob at crazybob.org (Bob Lee)
Date: Mon, 16 Nov 2009 08:07:10 -0800
Subject: [concurrency-interest] jsr166y classes now in jdk7m5
In-Reply-To: <612579.5731.qm@web32203.mail.mud.yahoo.com>
References:
<554927.5702.qm@web32205.mail.mud.yahoo.com>
<4B0077EF.1050808@cs.oswego.edu>
<1ccfd1c10911151814u32ab9ea6t2333b8cc1d44a6dd@mail.gmail.com>
<612579.5731.qm@web32203.mail.mud.yahoo.com>
Message-ID:
Alex,
I've been working on MapMaker full time for the past 2 weeks and do hope to
get it into JDK 7. It will have simple LRU-based (possibly combined w/
LFU-based) eviction. You won't be able to plug in custom eviction
algorithms, but it will make a for an effective, fast, concurrent,
general-purpose, in-memory cache that will improve upon soft references
without sacrificing ease of use. I liken it to LinkedHashMap.removeEldest().
I understand that the JDK 7 schedule is kind of up in the air at the moment,
but Doug and Martin are right--if MapMaker doesn't make it in, it's not the
end of the world. We can just continue to import Google Collections.
Bob
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From alexdmiller at yahoo.com Mon Nov 16 11:25:57 2009
From: alexdmiller at yahoo.com (Alex Miller)
Date: Mon, 16 Nov 2009 08:25:57 -0800 (PST)
Subject: [concurrency-interest] jsr166y classes now in jdk7m5
In-Reply-To:
References:
<554927.5702.qm@web32205.mail.mud.yahoo.com>
<4B0077EF.1050808@cs.oswego.edu>
<1ccfd1c10911151814u32ab9ea6t2333b8cc1d44a6dd@mail.gmail.com>
<612579.5731.qm@web32203.mail.mud.yahoo.com>
Message-ID: <940509.28129.qm@web32202.mail.mud.yahoo.com>
Sounds very cool. I'm sure my team would love to take a look at it if you wanted any review (not that you have any lack of expert reviewers, I'm sure :).
>
>From: Bob Lee
>To: Alex Miller
>Cc: Martin Buchholz ; Doug Lea ; concurrency-interest at cs.oswego.edu
>Sent: Mon, November 16, 2009 10:07:10 AM
>Subject: Re: [concurrency-interest] jsr166y classes now in jdk7m5
>
>Alex,
>
>
>I've been working on MapMaker full time for the past 2 weeks and do hope to get it into JDK 7. It will have simple LRU-based (possibly combined w/ LFU-based) eviction. You won't be able to plug in custom eviction algorithms, but it will make a for an effective, fast, concurrent, general-purpose, in-memory cache that will improve upon soft references without sacrificing ease of use. I liken it to LinkedHashMap.removeEldest().
>
>
>I understand that the JDK 7 schedule is kind of up in the air at the moment, but Doug and Martin are right--if MapMaker doesn't make it in, it's not the end of the world. We can just continue to import Google Collections.
>
>
>Bob
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From crazybob at crazybob.org Mon Nov 16 11:28:16 2009
From: crazybob at crazybob.org (Bob Lee)
Date: Mon, 16 Nov 2009 08:28:16 -0800
Subject: [concurrency-interest] jsr166y classes now in jdk7m5
In-Reply-To: <940509.28129.qm@web32202.mail.mud.yahoo.com>
References:
<554927.5702.qm@web32205.mail.mud.yahoo.com>
<4B0077EF.1050808@cs.oswego.edu>
<1ccfd1c10911151814u32ab9ea6t2333b8cc1d44a6dd@mail.gmail.com>
<612579.5731.qm@web32203.mail.mud.yahoo.com>
<940509.28129.qm@web32202.mail.mud.yahoo.com>
Message-ID:
On Mon, Nov 16, 2009 at 8:25 AM, Alex Miller wrote:
> Sounds very cool. I'm sure my team would love to take a look at it if you
> wanted any review (not that you have any lack of expert reviewers, I'm sure
> :).
>
Thanks for the offer! I'll ping you when I check it in.
Bob
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From bryan at systap.com Mon Nov 16 12:02:06 2009
From: bryan at systap.com (Bryan Thompson)
Date: Mon, 16 Nov 2009 11:02:06 -0600
Subject: [concurrency-interest] jsr166y classes now in jdk7m5
In-Reply-To:
References:
<554927.5702.qm@web32205.mail.mud.yahoo.com>
<4B0077EF.1050808@cs.oswego.edu>
<1ccfd1c10911151814u32ab9ea6t2333b8cc1d44a6dd@mail.gmail.com>
<612579.5731.qm@web32203.mail.mud.yahoo.com>
Message-ID:
Bob,
I posted a little while ago looking for a concurrent LRU (or similar eviction policy). I am looking at the 1.0-rc4 download of the google collections[1]. Looking at MapMaker, I see support for time-based eviction. However, what we really want is support for access-based eviction orders which are triggered based on the RAM utilized by the cache so we can manage the cache size in terms of the percentage of the heap which is dedicated to buffering data. Our application is a clustered database. There is really no reason to evict records from the cache just because they are old since the cache would just become "cold". Instead, we would like to preserve records in the cache and evict them when the cache would exceed a configured memory limit.
I've done several implementations of this, but none of them are based on striped locking or non-blocking operations which limits their potential concurrency. I've improved performance of a blocking cache implementation significantly by doing many evictions at once when the cache is full (cheap hack to reduce the lock contention), but I would really love to find a high performance concurrent cache with a pluggable eviction policy. Am I just missing how to do this with MapMaker? If I can do this with MapMaker, I would definately be happy to provide feedback on the implementation and its performance.
Thanks,
-bryan
[1] http://code.google.com/p/google-collections/
________________________________
From: concurrency-interest-bounces at cs.oswego.edu [mailto:concurrency-interest-bounces at cs.oswego.edu] On Behalf Of Bob Lee
Sent: Monday, November 16, 2009 11:07 AM
To: Alex Miller
Cc: Martin Buchholz; Doug Lea; concurrency-interest at cs.oswego.edu
Subject: Re: [concurrency-interest] jsr166y classes now in jdk7m5
Alex,
I've been working on MapMaker full time for the past 2 weeks and do hope to get it into JDK 7. It will have simple LRU-based (possibly combined w/ LFU-based) eviction. You won't be able to plug in custom eviction algorithms, but it will make a for an effective, fast, concurrent, general-purpose, in-memory cache that will improve upon soft references without sacrificing ease of use. I liken it to LinkedHashMap.removeEldest().
I understand that the JDK 7 schedule is kind of up in the air at the moment, but Doug and Martin are right--if MapMaker doesn't make it in, it's not the end of the world. We can just continue to import Google Collections.
Bob
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From raghuram.nidagal at gmail.com Tue Nov 17 23:34:29 2009
From: raghuram.nidagal at gmail.com (raghuram nidagal)
Date: Wed, 18 Nov 2009 10:04:29 +0530
Subject: [concurrency-interest] Question on compareAndSet
Message-ID: <7874b1f60911172034l2fe87ba1j8de47d2f21d15e1f@mail.gmail.com>
Hi,
The documentation says "The compareAndSet method is not a general
replacement for locking. It applies only when critical updates for an object
are confined to a* single* variable"
Can someone explain what this means? What are the scenarios where
compareAndSet cannot be used for locking?
Thanks
Raghu
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From davidcholmes at aapt.net.au Tue Nov 17 23:44:51 2009
From: davidcholmes at aapt.net.au (David Holmes)
Date: Wed, 18 Nov 2009 14:44:51 +1000
Subject: [concurrency-interest] Question on compareAndSet
In-Reply-To: <7874b1f60911172034l2fe87ba1j8de47d2f21d15e1f@mail.gmail.com>
Message-ID:
Hi Raghu,
compareAndSet can only update a single variable, whereas locking can enforce
an atomic action over as many variables as you like. Using multiple
compareAndSets across different variables does not give you atomicity over
the set actions.
For example suppose you have a class Point:
class Point {
int x, y;
void move(int newX, int newY) {
x = newX;
y = newY;
}
}
For move(a,b) to be an atomic operation you need to use locking - eg
synchronize the move() method. If you instead tried to do seperate CAS
operations on x and y, you could end up with an x from one move() and a y
from a distinct move() and that would violate the property of the Point,
that it can only exist in an x,y position to which it has been moved.
HTH
David Holmes
-----Original Message-----
From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of raghuram
nidagal
Sent: Wednesday, 18 November 2009 2:34 PM
To: concurrency-interest at cs.oswego.edu
Subject: [concurrency-interest] Question on compareAndSet
Hi,
The documentation says "The compareAndSet method is not a general
replacement for locking. It applies only when critical updates for an object
are confined to a single variable"
Can someone explain what this means? What are the scenarios where
compareAndSet cannot be used for locking?
Thanks
Raghu
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From raghuram.nidagal at gmail.com Wed Nov 18 00:29:11 2009
From: raghuram.nidagal at gmail.com (raghuram nidagal)
Date: Wed, 18 Nov 2009 10:59:11 +0530
Subject: [concurrency-interest] Question on compareAndSet
In-Reply-To:
References: <7874b1f60911172034l2fe87ba1j8de47d2f21d15e1f@mail.gmail.com>
Message-ID: <7874b1f60911172129t6c5a7c93odaba7fcb341d61c4@mail.gmail.com>
Thanks David.
I assume compareAndSet on a single variable by itself can be used to provide
locking functionality though..
while(notDone){
if(x.compareAndSet(true,false)){
//do something
notDone=false;
x.set(false);
}
else{
sleep..
}
}
is that different from synchronized except that this code does not block
trying to acquire the lock whereas synchronized would block ?
On Wed, Nov 18, 2009 at 10:14 AM, David Holmes wrote:
> Hi Raghu,
>
> compareAndSet can only update a single variable, whereas locking can
> enforce an atomic action over as many variables as you like. Using multiple
> compareAndSets across different variables does not give you atomicity over
> the set actions.
>
> For example suppose you have a class Point:
>
> class Point {
> int x, y;
> void move(int newX, int newY) {
> x = newX;
> y = newY;
> }
> }
>
> For move(a,b) to be an atomic operation you need to use locking - eg
> synchronize the move() method. If you instead tried to do seperate CAS
> operations on x and y, you could end up with an x from one move() and a y
> from a distinct move() and that would violate the property of the Point,
> that it can only exist in an x,y position to which it has been moved.
>
> HTH
>
> David Holmes
>
> -----Original Message-----
> *From:* concurrency-interest-bounces at cs.oswego.edu [mailto:
> concurrency-interest-bounces at cs.oswego.edu]*On Behalf Of *raghuram nidagal
> *Sent:* Wednesday, 18 November 2009 2:34 PM
> *To:* concurrency-interest at cs.oswego.edu
> *Subject:* [concurrency-interest] Question on compareAndSet
>
> Hi,
> The documentation says "The compareAndSet method is not a general
> replacement for locking. It applies only when critical updates for an object
> are confined to a* single* variable"
> Can someone explain what this means? What are the scenarios where
> compareAndSet cannot be used for locking?
> Thanks
> Raghu
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From davidcholmes at aapt.net.au Wed Nov 18 00:36:00 2009
From: davidcholmes at aapt.net.au (David Holmes)
Date: Wed, 18 Nov 2009 15:36:00 +1000
Subject: [concurrency-interest] Question on compareAndSet
In-Reply-To: <7874b1f60911172129t6c5a7c93odaba7fcb341d61c4@mail.gmail.com>
Message-ID:
You can build a lock out of compareAndSet - though to do it properly (no
busy-waiting, no time-based polling) you also need LockSupport.park. See how
ReentrantLock is implemented in terms of AbstractQueuedSynchronizer.
But the CAS documentation was not referring to the ability to build locks
out of CAS.
Cheers,
David
-----Original Message-----
From: raghuram nidagal [mailto:raghuram.nidagal at gmail.com]
Sent: Wednesday, 18 November 2009 3:29 PM
To: dholmes at ieee.org
Cc: concurrency-interest at cs.oswego.edu
Subject: Re: [concurrency-interest] Question on compareAndSet
Thanks David.
I assume compareAndSet on a single variable by itself can be used to
provide locking functionality though..
while(notDone){
if(x.compareAndSet(true,false)){
//do something
notDone=false;
x.set(false);
}
else{
sleep..
}
}
is that different from synchronized except that this code does not block
trying to acquire the lock whereas synchronized would block ?
On Wed, Nov 18, 2009 at 10:14 AM, David Holmes
wrote:
Hi Raghu,
compareAndSet can only update a single variable, whereas locking can
enforce an atomic action over as many variables as you like. Using multiple
compareAndSets across different variables does not give you atomicity over
the set actions.
For example suppose you have a class Point:
class Point {
int x, y;
void move(int newX, int newY) {
x = newX;
y = newY;
}
}
For move(a,b) to be an atomic operation you need to use locking - eg
synchronize the move() method. If you instead tried to do seperate CAS
operations on x and y, you could end up with an x from one move() and a y
from a distinct move() and that would violate the property of the Point,
that it can only exist in an x,y position to which it has been moved.
HTH
David Holmes
-----Original Message-----
From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of raghuram
nidagal
Sent: Wednesday, 18 November 2009 2:34 PM
To: concurrency-interest at cs.oswego.edu
Subject: [concurrency-interest] Question on compareAndSet
Hi,
The documentation says "The compareAndSet method is not a general
replacement for locking. It applies only when critical updates for an object
are confined to a single variable"
Can someone explain what this means? What are the scenarios where
compareAndSet cannot be used for locking?
Thanks
Raghu
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From raghuram.nidagal at gmail.com Wed Nov 18 00:41:43 2009
From: raghuram.nidagal at gmail.com (raghuram nidagal)
Date: Wed, 18 Nov 2009 11:11:43 +0530
Subject: [concurrency-interest] Question on compareAndSet
In-Reply-To:
References: <7874b1f60911172129t6c5a7c93odaba7fcb341d61c4@mail.gmail.com>
Message-ID: <7874b1f60911172141r539f482cwdf8002d0b65f4a8e@mail.gmail.com>
Thanks David
On Wed, Nov 18, 2009 at 11:06 AM, David Holmes wrote:
> You can build a lock out of compareAndSet - though to do it properly (no
> busy-waiting, no time-based polling) you also need LockSupport.park. See how
> ReentrantLock is implemented in terms of AbstractQueuedSynchronizer.
>
> But the CAS documentation was not referring to the ability to build locks
> out of CAS.
>
> Cheers,
> David
>
> -----Original Message-----
> *From:* raghuram nidagal [mailto:raghuram.nidagal at gmail.com]
> *Sent:* Wednesday, 18 November 2009 3:29 PM
> *To:* dholmes at ieee.org
> *Cc:* concurrency-interest at cs.oswego.edu
> *Subject:* Re: [concurrency-interest] Question on compareAndSet
>
> Thanks David.
> I assume compareAndSet on a single variable by itself can be used to
> provide locking functionality though..
> while(notDone){
> if(x.compareAndSet(true,false)){
> //do something
> notDone=false;
> x.set(false);
> }
> else{
> sleep..
> }
> }
> is that different from synchronized except that this code does not block
> trying to acquire the lock whereas synchronized would block ?
>
> On Wed, Nov 18, 2009 at 10:14 AM, David Holmes wrote:
>
>> Hi Raghu,
>>
>> compareAndSet can only update a single variable, whereas locking can
>> enforce an atomic action over as many variables as you like. Using multiple
>> compareAndSets across different variables does not give you atomicity over
>> the set actions.
>>
>> For example suppose you have a class Point:
>>
>> class Point {
>> int x, y;
>> void move(int newX, int newY) {
>> x = newX;
>> y = newY;
>> }
>> }
>>
>> For move(a,b) to be an atomic operation you need to use locking - eg
>> synchronize the move() method. If you instead tried to do seperate CAS
>> operations on x and y, you could end up with an x from one move() and a y
>> from a distinct move() and that would violate the property of the Point,
>> that it can only exist in an x,y position to which it has been moved.
>>
>> HTH
>>
>> David Holmes
>>
>> -----Original Message-----
>> *From:* concurrency-interest-bounces at cs.oswego.edu [mailto:
>> concurrency-interest-bounces at cs.oswego.edu]*On Behalf Of *raghuram
>> nidagal
>> *Sent:* Wednesday, 18 November 2009 2:34 PM
>> *To:* concurrency-interest at cs.oswego.edu
>> *Subject:* [concurrency-interest] Question on compareAndSet
>>
>> Hi,
>> The documentation says "The compareAndSet method is not a general
>> replacement for locking. It applies only when critical updates for an object
>> are confined to a* single* variable"
>> Can someone explain what this means? What are the scenarios where
>> compareAndSet cannot be used for locking?
>> Thanks
>> Raghu
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From jed at atlassian.com Wed Nov 18 22:43:12 2009
From: jed at atlassian.com (Jed Wesley-Smith)
Date: Thu, 19 Nov 2009 14:43:12 +1100
Subject: [concurrency-interest] Question on compareAndSet
In-Reply-To: <7874b1f60911172129t6c5a7c93odaba7fcb341d61c4@mail.gmail.com>
References: <7874b1f60911172034l2fe87ba1j8de47d2f21d15e1f@mail.gmail.com>
<7874b1f60911172129t6c5a7c93odaba7fcb341d61c4@mail.gmail.com>
Message-ID: <4B04BED0.7090000@atlassian.com>
raghuram,
You are implementing what is known as a TestAndSet (TAS) lock. Such an
algorithm is quite efficient in the uncontended case, but can have
absolutely dreadful performance degradation as the rate of contention
goes up. For a detailed description of why see "The Art of
Multiprocessor Programming" (Herlihy, Shavit) pg 144-146.
cheers,
jed.
raghuram nidagal wrote:
> Thanks David.
> I assume compareAndSet on a single variable by itself can be used to
> provide locking functionality though..
> while(notDone){
> if(x.compareAndSet(true,false)){
> //do something
> notDone=false;
> x.set(false);
> }
> else{
> sleep..
> }
> }
> is that different from synchronized except that this code does not
> block trying to acquire the lock whereas synchronized would block ?
>
> On Wed, Nov 18, 2009 at 10:14 AM, David Holmes
> > wrote:
>
> Hi Raghu,
>
> compareAndSet can only update a single variable, whereas locking
> can enforce an atomic action over as many variables as you like.
> Using multiple compareAndSets across different variables does not
> give you atomicity over the set actions.
>
> For example suppose you have a class Point:
>
> class Point {
> int x, y;
> void move(int newX, int newY) {
> x = newX;
> y = newY;
> }
> }
>
> For move(a,b) to be an atomic operation you need to use locking -
> eg synchronize the move() method. If you instead tried to do
> seperate CAS operations on x and y, you could end up with an x
> from one move() and a y from a distinct move() and that would
> violate the property of the Point, that it can only exist in an
> x,y position to which it has been moved.
>
> HTH
>
> David Holmes
>
> -----Original Message-----
> *From:* concurrency-interest-bounces at cs.oswego.edu
>
> [mailto:concurrency-interest-bounces at cs.oswego.edu
> ]*On Behalf
> Of *raghuram nidagal
> *Sent:* Wednesday, 18 November 2009 2:34 PM
> *To:* concurrency-interest at cs.oswego.edu
>
> *Subject:* [concurrency-interest] Question on compareAndSet
>
> Hi,
> The documentation says "The compareAndSet method is not a
> general replacement for locking. It applies only when critical
> updates for an object are confined to a/ single/ variable"
> Can someone explain what this means? What are the scenarios
> where compareAndSet cannot be used for locking?
> Thanks
> Raghu
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
From jed at atlassian.com Wed Nov 18 23:07:24 2009
From: jed at atlassian.com (Jed Wesley-Smith)
Date: Thu, 19 Nov 2009 15:07:24 +1100
Subject: [concurrency-interest] Question on compareAndSet
In-Reply-To:
References:
Message-ID: <4B04C47C.2080104@atlassian.com>
You can though get atomic updates by making a composite value for the
point (by value I mean an immutable class of immutable members) and
using that. To reuse the example:
class Point {
final AtomicReference location = new
AtomicReference(new Location(0, 0));
boolean move(Location from, Location to) {
return location.compareAndSet(from, to);
}
Location at() {return location.get();}
}
class Location {
final int x, y;
Location(final int x, final int y) {
this.x = x;
this.y = y;
}
}
(of course, Point should really be immutable anyway, Things move around
from point to point, but that's another topic entirely, see Are we there
yet from Rich Hickey:
http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey or,
there is no such thing as a mutable value!
cheers,
jed.
David Holmes wrote:
> Hi Raghu,
>
> compareAndSet can only update a single variable, whereas locking can
> enforce an atomic action over as many variables as you like. Using
> multiple compareAndSets across different variables does not give you
> atomicity over the set actions.
>
> For example suppose you have a class Point:
>
> class Point {
> int x, y;
> void move(int newX, int newY) {
> x = newX;
> y = newY;
> }
> }
>
> For move(a,b) to be an atomic operation you need to use locking - eg
> synchronize the move() method. If you instead tried to do seperate CAS
> operations on x and y, you could end up with an x from one move() and
> a y from a distinct move() and that would violate the property of the
> Point, that it can only exist in an x,y position to which it has been
> moved.
>
> HTH
>
> David Holmes
>
> -----Original Message-----
> *From:* concurrency-interest-bounces at cs.oswego.edu
> [mailto:concurrency-interest-bounces at cs.oswego.edu]*On Behalf Of
> *raghuram nidagal
> *Sent:* Wednesday, 18 November 2009 2:34 PM
> *To:* concurrency-interest at cs.oswego.edu
> *Subject:* [concurrency-interest] Question on compareAndSet
>
> Hi,
> The documentation says "The compareAndSet method is not a general
> replacement for locking. It applies only when critical updates for
> an object are confined to a/ single/ variable"
> Can someone explain what this means? What are the scenarios where
> compareAndSet cannot be used for locking?
> Thanks
> Raghu
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
From raghuram.nidagal at gmail.com Wed Nov 18 23:07:28 2009
From: raghuram.nidagal at gmail.com (raghuram nidagal)
Date: Thu, 19 Nov 2009 09:37:28 +0530
Subject: [concurrency-interest] Question on compareAndSet
In-Reply-To: <4B04BED0.7090000@atlassian.com>
References: <7874b1f60911172034l2fe87ba1j8de47d2f21d15e1f@mail.gmail.com>
<7874b1f60911172129t6c5a7c93odaba7fcb341d61c4@mail.gmail.com>
<4B04BED0.7090000@atlassian.com>
Message-ID: <7874b1f60911182007t47e5f5f1ubb60403a75cb2e4f@mail.gmail.com>
Thanks Jed. I will take a look.
On Thu, Nov 19, 2009 at 9:13 AM, Jed Wesley-Smith wrote:
> raghuram,
>
> You are implementing what is known as a TestAndSet (TAS) lock. Such an
> algorithm is quite efficient in the uncontended case, but can have
> absolutely dreadful performance degradation as the rate of contention goes
> up. For a detailed description of why see "The Art of Multiprocessor
> Programming" (Herlihy, Shavit) pg 144-146.
>
> cheers,
> jed.
>
> raghuram nidagal wrote:
>
>> Thanks David.
>> I assume compareAndSet on a single variable by itself can be used to
>> provide locking functionality though..
>> while(notDone){
>> if(x.compareAndSet(true,false)){
>> //do something
>> notDone=false;
>> x.set(false);
>> }
>> else{
>> sleep..
>> }
>> }
>> is that different from synchronized except that this code does not block
>> trying to acquire the lock whereas synchronized would block ?
>> On Wed, Nov 18, 2009 at 10:14 AM, David Holmes <
>> davidcholmes at aapt.net.au > wrote:
>>
>> Hi Raghu,
>> compareAndSet can only update a single variable, whereas locking
>> can enforce an atomic action over as many variables as you like.
>> Using multiple compareAndSets across different variables does not
>> give you atomicity over the set actions.
>> For example suppose you have a class Point:
>> class Point {
>> int x, y;
>> void move(int newX, int newY) {
>> x = newX;
>> y = newY;
>> }
>> }
>> For move(a,b) to be an atomic operation you need to use locking -
>> eg synchronize the move() method. If you instead tried to do
>> seperate CAS operations on x and y, you could end up with an x
>> from one move() and a y from a distinct move() and that would
>> violate the property of the Point, that it can only exist in an
>> x,y position to which it has been moved.
>> HTH
>> David Holmes
>> -----Original Message-----
>> *From:* concurrency-interest-bounces at cs.oswego.edu
>>
>> [mailto:concurrency-interest-bounces at cs.oswego.edu
>> ]*On Behalf
>> Of *raghuram nidagal
>> *Sent:* Wednesday, 18 November 2009 2:34 PM
>> *To:* concurrency-interest at cs.oswego.edu
>>
>> *Subject:* [concurrency-interest] Question on compareAndSet
>>
>> Hi,
>> The documentation says "The compareAndSet method is not a
>> general replacement for locking. It applies only when critical
>> updates for an object are confined to a/ single/ variable"
>> Can someone explain what this means? What are the scenarios
>> where compareAndSet cannot be used for locking?
>> Thanks
>> Raghu
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From normelton at gmail.com Wed Nov 18 23:46:16 2009
From: normelton at gmail.com (Norman Elton)
Date: Wed, 18 Nov 2009 23:46:16 -0500
Subject: [concurrency-interest] Performance of ReentrantReadWriteLock
Message-ID: <6b3a7f010911182046n3b8a3a69mcc9521d6a1ed223d@mail.gmail.com>
I've done some very basic testing of a ReentrantReadWriteLock vs.
synchronized. I fired up five threads, each of which is accessing a
shared Map. At first, I did 99% read operations, then
100% read operations. Initial testing, with no locking or
synchronization, proved about 8M operations per second per thread.
Super.
Then I tested synchronizing the get() and put() methods. Performance
dropped to about 700K operations per second. Synchronization obviously
has a large overhead.
Strange thing is, the ReentrantReadWriteLock performed just about as
well. Even in a 100% read environment, where I would think threads
would never have to block for one another.
Am I missing something here? Shouldn't I be seeing significantly
better numbers for the ReentrantReadWriteLock? Presumably, it's
allowing multiple threads to hit the hash at the same time. I would
expect numbers somewhere between the synchronizing hash and the
completely untouched HashMap.
Thoughts? Thanks!
Norman
From david.lloyd at redhat.com Thu Nov 19 00:01:41 2009
From: david.lloyd at redhat.com (David M. Lloyd)
Date: Wed, 18 Nov 2009 23:01:41 -0600
Subject: [concurrency-interest] Performance of ReentrantReadWriteLock
In-Reply-To: <6b3a7f010911182046n3b8a3a69mcc9521d6a1ed223d@mail.gmail.com>
References: <6b3a7f010911182046n3b8a3a69mcc9521d6a1ed223d@mail.gmail.com>
Message-ID: <4B04D135.9030002@redhat.com>
At a guess, I'd hazard that two things are taking effect.
1) *Lock are significantly faster than synchronization in your environment,
across the board. I believe this was the case for most or all Sun Java 5
JVM releases on Intel, though I could be mistaken there.
2) Map operations are so short that there's no significant contention for
the lock anyway. If you were holding the lock across, say, 50 to 100
operations maybe there'd be a bigger difference.
From my experience, a RWLock is only a win when the operations are
relatively long-lasting *and* it's a mostly-read situation. But often when
you're in the almost-all-reads situation, using a copy-on-write methodology
can be even better (no lock on the read path at all, plus in many cases you
can easily achieve cool snapshot semantics too).
- DML
On 11/18/2009 10:46 PM, Norman Elton wrote:
> I've done some very basic testing of a ReentrantReadWriteLock vs.
> synchronized. I fired up five threads, each of which is accessing a
> shared Map. At first, I did 99% read operations, then
> 100% read operations. Initial testing, with no locking or
> synchronization, proved about 8M operations per second per thread.
> Super.
>
> Then I tested synchronizing the get() and put() methods. Performance
> dropped to about 700K operations per second. Synchronization obviously
> has a large overhead.
>
> Strange thing is, the ReentrantReadWriteLock performed just about as
> well. Even in a 100% read environment, where I would think threads
> would never have to block for one another.
>
> Am I missing something here? Shouldn't I be seeing significantly
> better numbers for the ReentrantReadWriteLock? Presumably, it's
> allowing multiple threads to hit the hash at the same time. I would
> expect numbers somewhere between the synchronizing hash and the
> completely untouched HashMap.
>
> Thoughts? Thanks!
>
> Norman
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
From bronee at gmail.com Thu Nov 19 00:09:17 2009
From: bronee at gmail.com (Brian S O'Neill)
Date: Wed, 18 Nov 2009 21:09:17 -0800
Subject: [concurrency-interest] Performance of ReentrantReadWriteLock
In-Reply-To: <6b3a7f010911182046n3b8a3a69mcc9521d6a1ed223d@mail.gmail.com>
References: <6b3a7f010911182046n3b8a3a69mcc9521d6a1ed223d@mail.gmail.com>
Message-ID: <4B04D2FD.8030804@gmail.com>
Lock implementations have a quick check step to see if there's no
contention. Since you have only one thread in both tests, there is no
contention at all. The "synchronized" monitor and the read write lock
both need to do the same work for this quick check. The read write lock
is not designed to be /necessarily/ faster at lock acquisition, but it
is designed to allow multiple reads without the lock being released. For
applications which hold the lock only briefly, use of "synchronized"
will do fine.
Norman Elton wrote:
> I've done some very basic testing of a ReentrantReadWriteLock vs.
> synchronized. I fired up five threads, each of which is accessing a
> shared Map. At first, I did 99% read operations, then
> 100% read operations. Initial testing, with no locking or
> synchronization, proved about 8M operations per second per thread.
> Super.
>
> Then I tested synchronizing the get() and put() methods. Performance
> dropped to about 700K operations per second. Synchronization obviously
> has a large overhead.
>
> Strange thing is, the ReentrantReadWriteLock performed just about as
> well. Even in a 100% read environment, where I would think threads
> would never have to block for one another.
>
> Am I missing something here? Shouldn't I be seeing significantly
> better numbers for the ReentrantReadWriteLock? Presumably, it's
> allowing multiple threads to hit the hash at the same time. I would
> expect numbers somewhere between the synchronizing hash and the
> completely untouched HashMap.
>
> Thoughts? Thanks!
>
> Norman
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
From bronee at gmail.com Thu Nov 19 00:13:08 2009
From: bronee at gmail.com (Brian S O'Neill)
Date: Wed, 18 Nov 2009 21:13:08 -0800
Subject: [concurrency-interest] Performance of ReentrantReadWriteLock
In-Reply-To: <4B04D2FD.8030804@gmail.com>
References: <6b3a7f010911182046n3b8a3a69mcc9521d6a1ed223d@mail.gmail.com>
<4B04D2FD.8030804@gmail.com>
Message-ID: <4B04D3E4.3060808@gmail.com>
Oops... misread that. You do have multiple threads. I guess the question
to ask would be, how fast is the map, and how many processors do you
have? The operations might finish before another thread gets scheduled
to execute.
Brian S O'Neill wrote:
> Lock implementations have a quick check step to see if there's no
> contention. Since you have only one thread in both tests, there is no
> contention at all. The "synchronized" monitor and the read write lock
> both need to do the same work for this quick check. The read write
> lock is not designed to be /necessarily/ faster at lock acquisition,
> but it is designed to allow multiple reads without the lock being
> released. For applications which hold the lock only briefly, use of
> "synchronized" will do fine.
>
> Norman Elton wrote:
>> I've done some very basic testing of a ReentrantReadWriteLock vs.
>> synchronized. I fired up five threads, each of which is accessing a
>> shared Map. At first, I did 99% read operations, then
>> 100% read operations. Initial testing, with no locking or
>> synchronization, proved about 8M operations per second per thread.
>> Super.
>>
>> Then I tested synchronizing the get() and put() methods. Performance
>> dropped to about 700K operations per second. Synchronization obviously
>> has a large overhead.
>>
>> Strange thing is, the ReentrantReadWriteLock performed just about as
>> well. Even in a 100% read environment, where I would think threads
>> would never have to block for one another.
>>
>> Am I missing something here? Shouldn't I be seeing significantly
>> better numbers for the ReentrantReadWriteLock? Presumably, it's
>> allowing multiple threads to hit the hash at the same time. I would
>> expect numbers somewhere between the synchronizing hash and the
>> completely untouched HashMap.
>>
>> Thoughts? Thanks!
>>
>> Norman
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>
From dev at davidsoergel.com Thu Nov 19 00:39:42 2009
From: dev at davidsoergel.com (David Soergel)
Date: Wed, 18 Nov 2009 21:39:42 -0800
Subject: [concurrency-interest] Conja-- an accidental jsr166y alternative
Message-ID: <6A620512-FFD1-41A6-86F6-DF64EA4773E7@davidsoergel.com>
Hi all,
I wrote a Java concurrency library a while back before I knew about jsr166y, and finally got around to writing up how it works. I realize I'm very late to the party here, but still I hope some of the ideas I implemented may interest you.
The main advantage of my library that I see at the moment is that it hides all the hard stuff behind syntactic sugar, and so should be very easy for a novice to adopt. I suspect it would be straightforward to provide a similarly easy-to-use wrapper around the jsr166y internals. I haven't yet done a detailed comparison though, so it may well be that jsr166y provides functionality that Conja lacks.
The project home page is at http://dev.davidsoergel.com/trac/conja/, and the most important design issues are described briefly at
http://dev.davidsoergel.com/trac/conja/wiki/PrinciplesOfOperation
A couple of those issues are: 1) I schedule nested tasks in depth-first order, with advantages much like work stealing; 2) I employ various strategies to conserve memory (primarily by not leaving tasks waiting around in queues); and 3) I construct Runnables lazily and concurrently from an iterator of task inputs. One consequence is that "pipelines" consisting of nested mapping iterators (i.e., iterators that apply a function to elements from an underlying iterator) can be used to provide the inputs, in which case the mappings are computed lazily and concurrently.
I've been using this for some time with excellent performance, so I think it works at least :)
Looking forward to any feedback you may have,
-ds
_______________________________________________________
David Soergel (650) 303-5324
dev at davidsoergel.com http://www.davidsoergel.com
_______________________________________________________
From davidcholmes at aapt.net.au Thu Nov 19 01:04:10 2009
From: davidcholmes at aapt.net.au (David Holmes)
Date: Thu, 19 Nov 2009 16:04:10 +1000
Subject: [concurrency-interest] Conja-- an accidental jsr166y alternative
In-Reply-To: <6A620512-FFD1-41A6-86F6-DF64EA4773E7@davidsoergel.com>
Message-ID:
David,
Looks very F# like :)
One thing (and I was just browsing) your DepthFirstThreadPoolExecutor
lifecycle management is not thread-safe. You can leak instances; there's no
sync or volatile to ensure visibility of the newly created instance, or of
updated cpu counts. There's no sync between shutting down and recreating. Is
the expectation that this will not be used directly but only from other
library internals which ensures a single-thread manages the executor? If not
then you need synchronization in various places.
Cheers,
David Holmes
> -----Original Message-----
> From: concurrency-interest-bounces at cs.oswego.edu
> [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of David
> Soergel
> Sent: Thursday, 19 November 2009 3:40 PM
> To: concurrency-interest at cs.oswego.edu
> Subject: [concurrency-interest] Conja-- an accidental jsr166y
> alternative
>
>
> Hi all,
>
> I wrote a Java concurrency library a while back before I knew
> about jsr166y, and finally got around to writing up how it works.
> I realize I'm very late to the party here, but still I hope some
> of the ideas I implemented may interest you.
>
> The main advantage of my library that I see at the moment is that
> it hides all the hard stuff behind syntactic sugar, and so should
> be very easy for a novice to adopt. I suspect it would be
> straightforward to provide a similarly easy-to-use wrapper around
> the jsr166y internals. I haven't yet done a detailed comparison
> though, so it may well be that jsr166y provides functionality
> that Conja lacks.
>
> The project home page is at
> http://dev.davidsoergel.com/trac/conja/, and the most important
> design issues are described briefly at
> http://dev.davidsoergel.com/trac/conja/wiki/PrinciplesOfOperation
>
> A couple of those issues are: 1) I schedule nested tasks in
> depth-first order, with advantages much like work stealing; 2) I
> employ various strategies to conserve memory (primarily by not
> leaving tasks waiting around in queues); and 3) I construct
> Runnables lazily and concurrently from an iterator of task
> inputs. One consequence is that "pipelines" consisting of nested
> mapping iterators (i.e., iterators that apply a function to
> elements from an underlying iterator) can be used to provide the
> inputs, in which case the mappings are computed lazily and concurrently.
>
> I've been using this for some time with excellent performance, so
> I think it works at least :)
>
> Looking forward to any feedback you may have,
>
> -ds
>
>
> _______________________________________________________
> David Soergel (650) 303-5324
> dev at davidsoergel.com http://www.davidsoergel.com
> _______________________________________________________
>
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
From dev at davidsoergel.com Thu Nov 19 01:19:44 2009
From: dev at davidsoergel.com (David Soergel)
Date: Wed, 18 Nov 2009 22:19:44 -0800
Subject: [concurrency-interest] Conja-- an accidental jsr166y alternative
In-Reply-To:
References:
Message-ID:
Hi David,
I'm not familiar with F# specifically, but you're right that using a functional programming style is the idea here :)
Regarding the DepthFirstThreadPoolExecutor, my expectation is that it's only used internally. I didn't just make it private since I figured it might come in handy in some other context, but in fact I've only ever used it from within the Parallel class. Still, I should synchronize it properly just in case. Thanks for catching that!
-ds
On Nov 18, 2009, at 10:04 PM, David Holmes wrote:
> David,
>
> Looks very F# like :)
>
> One thing (and I was just browsing) your DepthFirstThreadPoolExecutor
> lifecycle management is not thread-safe. You can leak instances; there's no
> sync or volatile to ensure visibility of the newly created instance, or of
> updated cpu counts. There's no sync between shutting down and recreating. Is
> the expectation that this will not be used directly but only from other
> library internals which ensures a single-thread manages the executor? If not
> then you need synchronization in various places.
>
> Cheers,
> David Holmes
>
>> -----Original Message-----
>> From: concurrency-interest-bounces at cs.oswego.edu
>> [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of David
>> Soergel
>> Sent: Thursday, 19 November 2009 3:40 PM
>> To: concurrency-interest at cs.oswego.edu
>> Subject: [concurrency-interest] Conja-- an accidental jsr166y
>> alternative
>>
>>
>> Hi all,
>>
>> I wrote a Java concurrency library a while back before I knew
>> about jsr166y, and finally got around to writing up how it works.
>> I realize I'm very late to the party here, but still I hope some
>> of the ideas I implemented may interest you.
>>
>> The main advantage of my library that I see at the moment is that
>> it hides all the hard stuff behind syntactic sugar, and so should
>> be very easy for a novice to adopt. I suspect it would be
>> straightforward to provide a similarly easy-to-use wrapper around
>> the jsr166y internals. I haven't yet done a detailed comparison
>> though, so it may well be that jsr166y provides functionality
>> that Conja lacks.
>>
>> The project home page is at
>> http://dev.davidsoergel.com/trac/conja/, and the most important
>> design issues are described briefly at
>> http://dev.davidsoergel.com/trac/conja/wiki/PrinciplesOfOperation
>>
>> A couple of those issues are: 1) I schedule nested tasks in
>> depth-first order, with advantages much like work stealing; 2) I
>> employ various strategies to conserve memory (primarily by not
>> leaving tasks waiting around in queues); and 3) I construct
>> Runnables lazily and concurrently from an iterator of task
>> inputs. One consequence is that "pipelines" consisting of nested
>> mapping iterators (i.e., iterators that apply a function to
>> elements from an underlying iterator) can be used to provide the
>> inputs, in which case the mappings are computed lazily and concurrently.
>>
>> I've been using this for some time with excellent performance, so
>> I think it works at least :)
>>
>> Looking forward to any feedback you may have,
>>
>> -ds
>>
>>
>> _______________________________________________________
>> David Soergel (650) 303-5324
>> dev at davidsoergel.com http://www.davidsoergel.com
>> _______________________________________________________
>>
>>
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
_______________________________________________________
David Soergel (650) 303-5324
dev at davidsoergel.com http://www.davidsoergel.com
_______________________________________________________
From i30817 at gmail.com Thu Nov 19 01:38:06 2009
From: i30817 at gmail.com (Paulo Levi)
Date: Thu, 19 Nov 2009 06:38:06 +0000
Subject: [concurrency-interest] Conja-- an accidental jsr166y alternative
In-Reply-To:
References:
Message-ID: <212322090911182238t37f6f797l3bcd2494e1c576d4@mail.gmail.com>
You have cool ideas.
I "made" (copied most of the concepts) these (terrible) classes for
scheduling/composing Callables. One of the situations i've found is exactly
the one you describe in the profileration of executors example you give,
however i needed to have the requirement that the subtask was only run once
at a time (huuuuuge memory sink). So i composed my composable callables
(terrible outdated name it has now) and sent it to a 1 thread executor just
for that subtask. How would your library handle things like that?
How about scheduling problems? (i'm having that too - one of my task runs
the subtask with the huuuuuugee memory requirement, in a LIFO order (with a
executor from Threads there, however another task - that doesn't know
anything about the first - also runs a slightly different version of the
same task/function -> things explode).
I don't see how could you keep the different Priorities consistent in the
same Executor (all those task + some that i might execute later should run
LIFO or FIFO and another should run as soon as possible) or other out there
combinations.
http://code.google.com/p/bookjar-utils/source/browse/BookJar-utils/src/util/ChainRunnable.java
http://code.google.com/p/bookjar-utils/source/browse/BookJar-utils/src/util/Threads.java
On Thu, Nov 19, 2009 at 6:19 AM, David Soergel wrote:
> Hi David,
>
> I'm not familiar with F# specifically, but you're right that using a
> functional programming style is the idea here :)
>
> Regarding the DepthFirstThreadPoolExecutor, my expectation is that it's
> only used internally. I didn't just make it private since I figured it
> might come in handy in some other context, but in fact I've only ever used
> it from within the Parallel class. Still, I should synchronize it properly
> just in case. Thanks for catching that!
>
> -ds
>
>
> On Nov 18, 2009, at 10:04 PM, David Holmes wrote:
>
> > David,
> >
> > Looks very F# like :)
> >
> > One thing (and I was just browsing) your DepthFirstThreadPoolExecutor
> > lifecycle management is not thread-safe. You can leak instances; there's
> no
> > sync or volatile to ensure visibility of the newly created instance, or
> of
> > updated cpu counts. There's no sync between shutting down and recreating.
> Is
> > the expectation that this will not be used directly but only from other
> > library internals which ensures a single-thread manages the executor? If
> not
> > then you need synchronization in various places.
> >
> > Cheers,
> > David Holmes
> >
> >> -----Original Message-----
> >> From: concurrency-interest-bounces at cs.oswego.edu
> >> [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of David
> >> Soergel
> >> Sent: Thursday, 19 November 2009 3:40 PM
> >> To: concurrency-interest at cs.oswego.edu
> >> Subject: [concurrency-interest] Conja-- an accidental jsr166y
> >> alternative
> >>
> >>
> >> Hi all,
> >>
> >> I wrote a Java concurrency library a while back before I knew
> >> about jsr166y, and finally got around to writing up how it works.
> >> I realize I'm very late to the party here, but still I hope some
> >> of the ideas I implemented may interest you.
> >>
> >> The main advantage of my library that I see at the moment is that
> >> it hides all the hard stuff behind syntactic sugar, and so should
> >> be very easy for a novice to adopt. I suspect it would be
> >> straightforward to provide a similarly easy-to-use wrapper around
> >> the jsr166y internals. I haven't yet done a detailed comparison
> >> though, so it may well be that jsr166y provides functionality
> >> that Conja lacks.
> >>
> >> The project home page is at
> >> http://dev.davidsoergel.com/trac/conja/, and the most important
> >> design issues are described briefly at
> >> http://dev.davidsoergel.com/trac/conja/wiki/PrinciplesOfOperation
> >>
> >> A couple of those issues are: 1) I schedule nested tasks in
> >> depth-first order, with advantages much like work stealing; 2) I
> >> employ various strategies to conserve memory (primarily by not
> >> leaving tasks waiting around in queues); and 3) I construct
> >> Runnables lazily and concurrently from an iterator of task
> >> inputs. One consequence is that "pipelines" consisting of nested
> >> mapping iterators (i.e., iterators that apply a function to
> >> elements from an underlying iterator) can be used to provide the
> >> inputs, in which case the mappings are computed lazily and concurrently.
> >>
> >> I've been using this for some time with excellent performance, so
> >> I think it works at least :)
> >>
> >> Looking forward to any feedback you may have,
> >>
> >> -ds
> >>
> >>
> >> _______________________________________________________
> >> David Soergel (650) 303-5324
> >> dev at davidsoergel.com http://www.davidsoergel.com
> >> _______________________________________________________
> >>
> >>
> >>
> >> _______________________________________________
> >> Concurrency-interest mailing list
> >> Concurrency-interest at cs.oswego.edu
> >> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >
>
>
> _______________________________________________________
> David Soergel (650) 303-5324
> dev at davidsoergel.com http://www.davidsoergel.com
> _______________________________________________________
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From dev at davidsoergel.com Thu Nov 19 02:46:40 2009
From: dev at davidsoergel.com (David Soergel)
Date: Wed, 18 Nov 2009 23:46:40 -0800
Subject: [concurrency-interest] Conja-- an accidental jsr166y alternative
In-Reply-To: <212322090911182238t37f6f797l3bcd2494e1c576d4@mail.gmail.com>
References:
<212322090911182238t37f6f797l3bcd2494e1c576d4@mail.gmail.com>
Message-ID:
Hi Paulo,
I'm sorry I don't entirely understand your questions... in the first case, given that the tasks need to run one at a time for memory reasons, what are you trying to accomplish by running them in a separate thread?
I think your second question asks whether you can exert fine-grained control over the task scheduling, i.e. by explicitly giving different tasks different priorities. Conja doesn't provide for that. It assumes that the tasks are independent of one another (that's what I mean by "functional style"), so there should be no need to impose scheduling constraints among them. In practice, Conja executes the tasks in a given batch in FIFO order. The trick is that nested tasks essentially inherit their priority; this helps tasks finish faster and thus get out of the way in terms of memory. If there is one task somewhere in the call tree that requires a lot of memory, Conja has no way of knowing that in advance, so it will continue to run other tasks on the rest of its worker threads concurrently. It sounds like you'd like to be able to a) postpone a task when you can predict that there's not enough memory currently available to finish it, and b) tell the executor to pause (i.e., finish running tasks but not start any new ones) in hopes of freeing up some memory so that the postponed task can run. These are interesting ideas... am I getting the gist of your problem?
-ds
On Nov 18, 2009, at 10:38 PM, Paulo Levi wrote:
> You have cool ideas.
> I "made" (copied most of the concepts) these (terrible) classes for
> scheduling/composing Callables. One of the situations i've found is exactly
> the one you describe in the profileration of executors example you give,
> however i needed to have the requirement that the subtask was only run once
> at a time (huuuuuge memory sink). So i composed my composable callables
> (terrible outdated name it has now) and sent it to a 1 thread executor just
> for that subtask. How would your library handle things like that?
>
> How about scheduling problems? (i'm having that too - one of my task runs
> the subtask with the huuuuuugee memory requirement, in a LIFO order (with a
> executor from Threads there, however another task - that doesn't know
> anything about the first - also runs a slightly different version of the
> same task/function -> things explode).
> I don't see how could you keep the different Priorities consistent in the
> same Executor (all those task + some that i might execute later should run
> LIFO or FIFO and another should run as soon as possible) or other out there
> combinations.
>
> http://code.google.com/p/bookjar-utils/source/browse/BookJar-utils/src/util/ChainRunnable.java
> http://code.google.com/p/bookjar-utils/source/browse/BookJar-utils/src/util/Threads.java
>
> On Thu, Nov 19, 2009 at 6:19 AM, David Soergel wrote:
>
>> Hi David,
>>
>> I'm not familiar with F# specifically, but you're right that using a
>> functional programming style is the idea here :)
>>
>> Regarding the DepthFirstThreadPoolExecutor, my expectation is that it's
>> only used internally. I didn't just make it private since I figured it
>> might come in handy in some other context, but in fact I've only ever used
>> it from within the Parallel class. Still, I should synchronize it properly
>> just in case. Thanks for catching that!
>>
>> -ds
>>
>>
>> On Nov 18, 2009, at 10:04 PM, David Holmes wrote:
>>
>>> David,
>>>
>>> Looks very F# like :)
>>>
>>> One thing (and I was just browsing) your DepthFirstThreadPoolExecutor
>>> lifecycle management is not thread-safe. You can leak instances; there's
>> no
>>> sync or volatile to ensure visibility of the newly created instance, or
>> of
>>> updated cpu counts. There's no sync between shutting down and recreating.
>> Is
>>> the expectation that this will not be used directly but only from other
>>> library internals which ensures a single-thread manages the executor? If
>> not
>>> then you need synchronization in various places.
>>>
>>> Cheers,
>>> David Holmes
>>>
>>>> -----Original Message-----
>>>> From: concurrency-interest-bounces at cs.oswego.edu
>>>> [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of David
>>>> Soergel
>>>> Sent: Thursday, 19 November 2009 3:40 PM
>>>> To: concurrency-interest at cs.oswego.edu
>>>> Subject: [concurrency-interest] Conja-- an accidental jsr166y
>>>> alternative
>>>>
>>>>
>>>> Hi all,
>>>>
>>>> I wrote a Java concurrency library a while back before I knew
>>>> about jsr166y, and finally got around to writing up how it works.
>>>> I realize I'm very late to the party here, but still I hope some
>>>> of the ideas I implemented may interest you.
>>>>
>>>> The main advantage of my library that I see at the moment is that
>>>> it hides all the hard stuff behind syntactic sugar, and so should
>>>> be very easy for a novice to adopt. I suspect it would be
>>>> straightforward to provide a similarly easy-to-use wrapper around
>>>> the jsr166y internals. I haven't yet done a detailed comparison
>>>> though, so it may well be that jsr166y provides functionality
>>>> that Conja lacks.
>>>>
>>>> The project home page is at
>>>> http://dev.davidsoergel.com/trac/conja/, and the most important
>>>> design issues are described briefly at
>>>> http://dev.davidsoergel.com/trac/conja/wiki/PrinciplesOfOperation
>>>>
>>>> A couple of those issues are: 1) I schedule nested tasks in
>>>> depth-first order, with advantages much like work stealing; 2) I
>>>> employ various strategies to conserve memory (primarily by not
>>>> leaving tasks waiting around in queues); and 3) I construct
>>>> Runnables lazily and concurrently from an iterator of task
>>>> inputs. One consequence is that "pipelines" consisting of nested
>>>> mapping iterators (i.e., iterators that apply a function to
>>>> elements from an underlying iterator) can be used to provide the
>>>> inputs, in which case the mappings are computed lazily and concurrently.
>>>>
>>>> I've been using this for some time with excellent performance, so
>>>> I think it works at least :)
>>>>
>>>> Looking forward to any feedback you may have,
>>>>
>>>> -ds
>>>>
>>>>
>>>> _______________________________________________________
>>>> David Soergel (650) 303-5324
>>>> dev at davidsoergel.com http://www.davidsoergel.com
>>>> _______________________________________________________
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Concurrency-interest mailing list
>>>> Concurrency-interest at cs.oswego.edu
>>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>
>>
>>
>> _______________________________________________________
>> David Soergel (650) 303-5324
>> dev at davidsoergel.com http://www.davidsoergel.com
>> _______________________________________________________
>>
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
_______________________________________________________
David Soergel (650) 303-5324
dev at davidsoergel.com http://www.davidsoergel.com
_______________________________________________________
From i30817 at gmail.com Thu Nov 19 03:18:14 2009
From: i30817 at gmail.com (Paulo Levi)
Date: Thu, 19 Nov 2009 08:18:14 +0000
Subject: [concurrency-interest] Conja-- an accidental jsr166y alternative
In-Reply-To:
References:
<212322090911182238t37f6f797l3bcd2494e1c576d4@mail.gmail.com>
Message-ID: <212322090911190018u5a9587e7v368b1410617fa68@mail.gmail.com>
It's not all of the tasks. As i can compose Callables i offload getting a
image to some services implemented as task. If one fails it tries the other
right?
So i composed the code that should be 1 threaded (including that one huge
one). If that fails i want to run another alternative, but that alternative
is not memory intensive so i can run many threads of that (concurrently
while the first awaits right).
Basically a way to say that tasks of a certain set of type should only
should run on a n? of threads concurrently (a number probably could be
derived from max memory and expected maximum memory use - that is, if you
want to go that way). Your idea of pausing the executor until the others
complete could have the same effect maybe if we just annotated the expected
memory consumption of that task.
For the second case not to complicate too much (its actually used in
conjunction with the first) i'm interested in 2 main things
1) As your library appears to use a singleton executor hidden by a static
method, was there any support at all for different queuing strategies (LIFO
i use), inclusevely across different calls. For example i have a problem in
my app that one of my Executors is FIFO (that contains the huge memory
task), but another functionality (in the main UI thread) calls a Executor
(single-threaded) that calls that task too. What is stumping me in just
having a shared executor like you is - well that new singleThreaded task
should execute as fast as possible (LIFO), but that conflicts with the FIFO
queue i already am using.
On Thu, Nov 19, 2009 at 7:46 AM, David Soergel wrote:
> Hi Paulo,
>
> I'm sorry I don't entirely understand your questions... in the first case,
> given that the tasks need to run one at a time for memory reasons, what are
> you trying to accomplish by running them in a separate thread?
>
> I think your second question asks whether you can exert fine-grained
> control over the task scheduling, i.e. by explicitly giving different tasks
> different priorities. Conja doesn't provide for that. It assumes that the
> tasks are independent of one another (that's what I mean by "functional
> style"), so there should be no need to impose scheduling constraints among
> them. In practice, Conja executes the tasks in a given batch in FIFO order.
> The trick is that nested tasks essentially inherit their priority; this
> helps tasks finish faster and thus get out of the way in terms of memory.
> If there is one task somewhere in the call tree that requires a lot of
> memory, Conja has no way of knowing that in advance, so it will continue to
> run other tasks on the rest of its worker threads concurrently. It sounds
> like you'd like to be able to a) postpone a task when you can predict that
> there's not enough memory currently available to finish it, and b) tell the
> executor to pause (i.e., finish running tasks but not start any new ones) in
> hopes of freeing up some memory so that the postponed task can run. These
> are interesting ideas... am I getting the gist of your problem?
>
> -ds
>
>
>
> On Nov 18, 2009, at 10:38 PM, Paulo Levi wrote:
>
> > You have cool ideas.
> > I "made" (copied most of the concepts) these (terrible) classes for
> > scheduling/composing Callables. One of the situations i've found is
> exactly
> > the one you describe in the profileration of executors example you give,
> > however i needed to have the requirement that the subtask was only run
> once
> > at a time (huuuuuge memory sink). So i composed my composable callables
> > (terrible outdated name it has now) and sent it to a 1 thread executor
> just
> > for that subtask. How would your library handle things like that?
> >
> > How about scheduling problems? (i'm having that too - one of my task runs
> > the subtask with the huuuuuugee memory requirement, in a LIFO order (with
> a
> > executor from Threads there, however another task - that doesn't know
> > anything about the first - also runs a slightly different version of the
> > same task/function -> things explode).
> > I don't see how could you keep the different Priorities consistent in the
> > same Executor (all those task + some that i might execute later should
> run
> > LIFO or FIFO and another should run as soon as possible) or other out
> there
> > combinations.
> >
> >
> http://code.google.com/p/bookjar-utils/source/browse/BookJar-utils/src/util/ChainRunnable.java
> >
> http://code.google.com/p/bookjar-utils/source/browse/BookJar-utils/src/util/Threads.java
> >
> > On Thu, Nov 19, 2009 at 6:19 AM, David Soergel
> wrote:
> >
> >> Hi David,
> >>
> >> I'm not familiar with F# specifically, but you're right that using a
> >> functional programming style is the idea here :)
> >>
> >> Regarding the DepthFirstThreadPoolExecutor, my expectation is that it's
> >> only used internally. I didn't just make it private since I figured it
> >> might come in handy in some other context, but in fact I've only ever
> used
> >> it from within the Parallel class. Still, I should synchronize it
> properly
> >> just in case. Thanks for catching that!
> >>
> >> -ds
> >>
> >>
> >> On Nov 18, 2009, at 10:04 PM, David Holmes wrote:
> >>
> >>> David,
> >>>
> >>> Looks very F# like :)
> >>>
> >>> One thing (and I was just browsing) your DepthFirstThreadPoolExecutor
> >>> lifecycle management is not thread-safe. You can leak instances;
> there's
> >> no
> >>> sync or volatile to ensure visibility of the newly created instance, or
> >> of
> >>> updated cpu counts. There's no sync between shutting down and
> recreating.
> >> Is
> >>> the expectation that this will not be used directly but only from other
> >>> library internals which ensures a single-thread manages the executor?
> If
> >> not
> >>> then you need synchronization in various places.
> >>>
> >>> Cheers,
> >>> David Holmes
> >>>
> >>>> -----Original Message-----
> >>>> From: concurrency-interest-bounces at cs.oswego.edu
> >>>> [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of David
> >>>> Soergel
> >>>> Sent: Thursday, 19 November 2009 3:40 PM
> >>>> To: concurrency-interest at cs.oswego.edu
> >>>> Subject: [concurrency-interest] Conja-- an accidental jsr166y
> >>>> alternative
> >>>>
> >>>>
> >>>> Hi all,
> >>>>
> >>>> I wrote a Java concurrency library a while back before I knew
> >>>> about jsr166y, and finally got around to writing up how it works.
> >>>> I realize I'm very late to the party here, but still I hope some
> >>>> of the ideas I implemented may interest you.
> >>>>
> >>>> The main advantage of my library that I see at the moment is that
> >>>> it hides all the hard stuff behind syntactic sugar, and so should
> >>>> be very easy for a novice to adopt. I suspect it would be
> >>>> straightforward to provide a similarly easy-to-use wrapper around
> >>>> the jsr166y internals. I haven't yet done a detailed comparison
> >>>> though, so it may well be that jsr166y provides functionality
> >>>> that Conja lacks.
> >>>>
> >>>> The project home page is at
> >>>> http://dev.davidsoergel.com/trac/conja/, and the most important
> >>>> design issues are described briefly at
> >>>> http://dev.davidsoergel.com/trac/conja/wiki/PrinciplesOfOperation
> >>>>
> >>>> A couple of those issues are: 1) I schedule nested tasks in
> >>>> depth-first order, with advantages much like work stealing; 2) I
> >>>> employ various strategies to conserve memory (primarily by not
> >>>> leaving tasks waiting around in queues); and 3) I construct
> >>>> Runnables lazily and concurrently from an iterator of task
> >>>> inputs. One consequence is that "pipelines" consisting of nested
> >>>> mapping iterators (i.e., iterators that apply a function to
> >>>> elements from an underlying iterator) can be used to provide the
> >>>> inputs, in which case the mappings are computed lazily and
> concurrently.
> >>>>
> >>>> I've been using this for some time with excellent performance, so
> >>>> I think it works at least :)
> >>>>
> >>>> Looking forward to any feedback you may have,
> >>>>
> >>>> -ds
> >>>>
> >>>>
> >>>> _______________________________________________________
> >>>> David Soergel (650) 303-5324
> >>>> dev at davidsoergel.com http://www.davidsoergel.com
> >>>> _______________________________________________________
> >>>>
> >>>>
> >>>>
> >>>> _______________________________________________
> >>>> Concurrency-interest mailing list
> >>>> Concurrency-interest at cs.oswego.edu
> >>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >>>
> >>
> >>
> >> _______________________________________________________
> >> David Soergel (650) 303-5324
> >> dev at davidsoergel.com http://www.davidsoergel.com
> >> _______________________________________________________
> >>
> >>
> >> _______________________________________________
> >> Concurrency-interest mailing list
> >> Concurrency-interest at cs.oswego.edu
> >> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >>
>
>
> _______________________________________________________
> David Soergel (650) 303-5324
> dev at davidsoergel.com http://www.davidsoergel.com
> _______________________________________________________
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From i30817 at gmail.com Thu Nov 19 03:19:16 2009
From: i30817 at gmail.com (Paulo Levi)
Date: Thu, 19 Nov 2009 08:19:16 +0000
Subject: [concurrency-interest] Conja-- an accidental jsr166y alternative
In-Reply-To: <212322090911190018u5a9587e7v368b1410617fa68@mail.gmail.com>
References:
<212322090911182238t37f6f797l3bcd2494e1c576d4@mail.gmail.com>
<212322090911190018u5a9587e7v368b1410617fa68@mail.gmail.com>
Message-ID: <212322090911190019p4f3b8c0qe9ca933ed980f6b0@mail.gmail.com>
One main thing obviously. Sorry about the misinformation.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From z8sbk at yahoo.com.ar Thu Nov 19 18:34:32 2009
From: z8sbk at yahoo.com.ar (Safe P.)
Date: Thu, 19 Nov 2009 15:34:32 -0800 (PST)
Subject: [concurrency-interest] [CPU Affinity] ThreadPoolExecutor to improve
"O.S Scheduler" ?
Message-ID: <119231.18710.qm@web111104.mail.gq1.yahoo.com>
Hi,
I'm very new to concurrent programming and I couldn't find anywhere if this is an issue or just a limitation.
?
I'm running several instances of a java process like "process.sh & process.sh & process.sh ..." in an HP-UX that runs over a 12-core machine.
When I use sar, top, and other utilities I can see that HP-UX is using just 1 core. It doesn't manage to assign one processor per process.
?
Can I get this using ThreadPoolExecutor (like one System.Runtime.exec() per thread)?
?
Unfortunately, this machine is a production server so I can't get access to it in order to do some test and verify that, and of course, if this make a significant time improvement.
Thank you very much in advanced.
--Matias
Yahoo! Cocina
Encontra las mejores recetas con Yahoo! Cocina.
http://ar.mujer.yahoo.com/cocina/
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From davidcholmes at aapt.net.au Thu Nov 19 18:45:22 2009
From: davidcholmes at aapt.net.au (David Holmes)
Date: Fri, 20 Nov 2009 09:45:22 +1000
Subject: [concurrency-interest] [CPU Affinity] ThreadPoolExecutor to
improve"O.S Scheduler" ?
In-Reply-To: <119231.18710.qm@web111104.mail.gq1.yahoo.com>
Message-ID:
Matias,
I'm not really understanding your problem/issue, but most systems have some
notion of processing domains that let you allocate resources (memory and
CPU) to a domain and then run specific processes in specific domains. On
Solaris this is done with processor sets, while on Linux there are CPU-sets.
I don't know what HP-UX has.
There are no Java API's to control thread or process affinity (other than by
exec'ing OS utilities to do it, or calling your own native code routines.
Normally, absent any domains, all processes (and all their threads) can run
on any available processor/core.
HTH.
David Holmes
-----Original Message-----
From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Safe P.
Sent: Friday, 20 November 2009 9:35 AM
To: concurrency-interest at cs.oswego.edu
Subject: [concurrency-interest] [CPU Affinity] ThreadPoolExecutor to
improve"O.S Scheduler" ?
Hi,
I'm very new to concurrent programming and I couldn't find anywhere
if this is an issue or just a limitation.
I'm running several instances of a java process like "process.sh &
process.sh & process.sh ..." in an HP-UX that runs over a 12-core machine.
When I use sar, top, and other utilities I can see that HP-UX is
using just 1 core. It doesn't manage to assign one processor per process.
Can I get this using ThreadPoolExecutor (like one
System.Runtime.exec() per thread)?
Unfortunately, this machine is a production server so I can't get
access to it in order to do some test and verify that, and of course, if
this make a significant time improvement.
Thank you very much in advanced.
--Matias
----------------------------------------------------------------------------
--
Encontra las mejores recetas con Yahoo! Cocina.
http://ar.mujer.yahoo.com/cocina/
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From aph at redhat.com Fri Nov 20 12:46:52 2009
From: aph at redhat.com (Andrew Haley)
Date: Fri, 20 Nov 2009 17:46:52 +0000
Subject: [concurrency-interest] park and unpark low-level details
Message-ID: <4B06D60C.2020005@redhat.com>
Something I've been wondering about.
In "The java.util.concurrent Synchronizer Framework" Doug writes:
<< This simple mechanism is similar to those used, at some level, in
the Solaris-9 thread library [11], in WIN32 "consumable events", and
in the Linux NPTL thread library, and so maps efficiently to each of
these on the most common platforms Java runs on. (However, the
current Sun Hotspot JVM reference implementation on Solaris and Linux
actually uses a pthread condvar in order to fit into the existing
runtime design.) >>
What do you man by this? I guess there's a nice way to map park and
unpark onto low-level NPTL primitives (futexes, perhaps?) Did you
have a sketch of a design for that?
It probably doesn't much matter, given that pthread mutex and conndvar
signal a fairly thin wrappers over futexes, but unparking a blocked
thread requires three pthread_ calls:
int status = pthread_mutex_lock(_mutex);
AnyWaiters = _nParked ;
status = pthread_mutex_unlock(_mutex);
if (AnyWaiters != 0) {
status = pthread_cond_signal(_cond);
}
(I realize that the mutex is necessary to prevent a race when signalling
a thread that's parking. I just wondered if you'd had another design in
mind.)
Thanks,
Andrew.
From aph at redhat.com Fri Nov 20 13:41:48 2009
From: aph at redhat.com (Andrew Haley)
Date: Fri, 20 Nov 2009 18:41:48 +0000
Subject: [concurrency-interest] park and unpark low-level details
In-Reply-To: <3D323829-DF05-41EE-A5E2-B9311C02CEEE@sun.com>
References: <4B06D60C.2020005@redhat.com>
<3D323829-DF05-41EE-A5E2-B9311C02CEEE@sun.com>
Message-ID: <4B06E2EC.2050301@redhat.com>
Dave Dice wrote:
> On 2009-11-20, at 12:46 PM, Andrew Haley wrote:
>
>> Something I've been wondering about.
>>
>> In "The java.util.concurrent Synchronizer Framework" Doug writes:
>>
>> << This simple mechanism is similar to those used, at some level, in
>> the Solaris-9 thread library [11], in WIN32 "consumable events", and
>> in the Linux NPTL thread library, and so maps efficiently to each of
>> these on the most common platforms Java runs on. (However, the
>> current Sun Hotspot JVM reference implementation on Solaris and Linux
>> actually uses a pthread condvar in order to fit into the existing
>> runtime design.) >>
>>
>> What do you man by this? I guess there's a nice way to map park and
>> unpark onto low-level NPTL primitives (futexes, perhaps?) Did you
>> have a sketch of a design for that?
>
> We preferred to use more standardized interfaces. I experimented
> with using futexes instead of the usual condvar-mutex-flag tuple but
> it wasn't particularly better.
I'm not surprised. I did some profiling, and even with quite heavily
contended locks the time spent in park and unpark is often down in
the noise. Amazing, really. :-)
> (Likewise, Solaris has low-level __lwp_park and __lwp_park
> interfaces that also work nicely, but they aren't officially exposed
> and subject change from release to release).
> One of the more interesting approaches is to use pipe pairs. (I
> left comments in the code that explain this in more detail).
> Perversely, this is one of the best implementations for Solaris and
> Linux, except that it can consume excessive number of file
> descriptors, which is why we're not using it.
Yes, I read that. I guess you'd use open() with O_NONBLOCK and
select() with a timeout for timed waits. This does have a really nice
feel to it; it's a shame file descriptors turn out to be such a scarce
resource.
>> It probably doesn't much matter, given that pthread mutex and conndvar
>> signal a fairly thin wrappers over futexes, but unparking a blocked
>> thread requires three pthread_ calls:
>>
>> int status = pthread_mutex_lock(_mutex);
>>
>> AnyWaiters = _nParked ;
>>
>> status = pthread_mutex_unlock(_mutex);
>>
>> if (AnyWaiters != 0) {
>> status = pthread_cond_signal(_cond);
>> }
>
> You're apparently looking at the PlatformEvent:: implementation and
> not Parker::. PlatformEvent:: is used by the built-in
> synchronization primitives and native C++ JVM internal mutexes and
> monitors, whereas Parker:: is infrastructure used by LockSupport.
> They're similar -- and someday should be reconciled -- but have
> slightly different semantics.
Ah, my mistake. However, exactly the same is true of Parker::park:
status = pthread_mutex_lock(_mutex);
s = _counter;
_counter = 1;
if (s < 1) {
status = pthread_mutex_unlock(_mutex);
status = pthread_cond_signal (_cond) ;
}
} else {
pthread_mutex_unlock(_mutex);
}
I suppose this question is more to do with the fact that it doesn't
quite feel right (to me) to be using all these pthread calls in the
lowest-level Java primitives, rather than anything real to do with
performance.
Thanks,
Andrew.
From z8sbk at yahoo.com.ar Fri Nov 20 14:35:07 2009
From: z8sbk at yahoo.com.ar (Safe P.)
Date: Fri, 20 Nov 2009 11:35:07 -0800 (PST)
Subject: [concurrency-interest] [CPU Affinity] ThreadPoolExecutor to
improve"O.S Scheduler" ?
In-Reply-To:
Message-ID: <761766.25527.qm@web111110.mail.gq1.yahoo.com>
David, thank you for your answer.
The problem is exactly this:
when I run? java -cp . MyProcess & java -cp .MyProcess & ... in a 12-core machine that runs HP-UX, all processes are assign to one processor.
That means that an instance must wait until the end of the previous instance to start. I want to run all instances in parallel, using all 12 processors. Is this possibly? Maybe using ThreadPoolExecutor to execute each instance of this "java -cp .."?
Thank you very much in advance!
--- El jue 19-nov-09, David Holmes escribi?:
De: David Holmes
Asunto: RE: [concurrency-interest] [CPU Affinity] ThreadPoolExecutor to improve"O.S Scheduler" ?
Para: "Safe P." , concurrency-interest at cs.oswego.edu
Fecha: jueves, 19 de noviembre de 2009, 9:45 pm
Matias,
?
I'm not really understanding your problem/issue, but most systems have
some notion of processing domains that let you allocate resources (memory and
CPU) to a domain and then run specific processes in specific domains. On Solaris
this is done with processor sets, while on Linux there are CPU-sets. I don't
know what HP-UX has.
?
There are no Java API's to control thread or process affinity (other than
by exec'ing OS utilities to do it, or calling your own native code
routines.
?
Normally, absent any domains, all processes (and all their threads) can
run on any available processor/core.
?
HTH.
?
David Holmes
-----Original Message-----
From:
concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Safe
P.
Sent: Friday, 20 November 2009 9:35 AM
To:
concurrency-interest at cs.oswego.edu
Subject: [concurrency-interest]
[CPU Affinity] ThreadPoolExecutor to improve"O.S Scheduler"
?
Hi,
I'm very new to concurrent programming and I couldn't find
anywhere if this is an issue or just a limitation.
?
I'm running several instances of a java process like "process.sh
& process.sh & process.sh ..." in an HP-UX that runs over a
12-core machine.
When I use sar, top, and other utilities I can see that HP-UX
is using just 1 core. It doesn't manage to assign one processor per
process.
?
Can I get this using ThreadPoolExecutor (like one
System.Runtime.exec() per thread)?
?
Unfortunately, this machine is a production server so I can't get
access to it in order to do some test and verify that, and of course, if
this make a significant time improvement.
Thank you very much in
advanced.
--Matias
Encontra las mejores recetas con Yahoo! Cocina.
http://ar.mujer.yahoo.com/cocina/
Yahoo! Cocina
Encontra las mejores recetas con Yahoo! Cocina.
http://ar.mujer.yahoo.com/cocina/
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From david.lloyd at redhat.com Fri Nov 20 14:45:05 2009
From: david.lloyd at redhat.com (David M. Lloyd)
Date: Fri, 20 Nov 2009 13:45:05 -0600
Subject: [concurrency-interest] [CPU Affinity] ThreadPoolExecutor
to improve"O.S Scheduler" ?
In-Reply-To: <761766.25527.qm@web111110.mail.gq1.yahoo.com>
References: <761766.25527.qm@web111110.mail.gq1.yahoo.com>
Message-ID: <4B06F1C1.8010100@redhat.com>
He's saying it's probably a config issue with your OS, not a Java problem.
- DML
On 11/20/2009 01:35 PM, Safe P. wrote:
> David, thank you for your answer.
>
> The problem is exactly this:
>
> when I run java -cp . MyProcess & java -cp .MyProcess & ... in a 12-core
> machine that runs HP-UX, all processes are assign to one processor.
>
> That means that an instance must wait until the end of the previous
> instance to start. I want to run all instances in parallel, using all 12
> processors. Is this possibly? Maybe using ThreadPoolExecutor to execute
> each instance of this "java -cp .."?
>
> Thank you very much in advance!
>
>
> --- El *jue 19-nov-09, David Holmes //* escribi?:
>
>
> De: David Holmes
> Asunto: RE: [concurrency-interest] [CPU Affinity] ThreadPoolExecutor
> to improve"O.S Scheduler" ?
> Para: "Safe P." , concurrency-interest at cs.oswego.edu
> Fecha: jueves, 19 de noviembre de 2009, 9:45 pm
>
> Matias,
> I'm not really understanding your problem/issue, but most systems
> have some notion of processing domains that let you allocate
> resources (memory and CPU) to a domain and then run specific
> processes in specific domains. On Solaris this is done with
> processor sets, while on Linux there are CPU-sets. I don't know what
> HP-UX has.
> There are no Java API's to control thread or process affinity (other
> than by exec'ing OS utilities to do it, or calling your own native
> code routines.
> Normally, absent any domains, all processes (and all their threads)
> can run on any available processor/core.
> HTH.
> David Holmes
>
> -----Original Message-----
> *From:* concurrency-interest-bounces at cs.oswego.edu
> [mailto:concurrency-interest-bounces at cs.oswego.edu]*On Behalf Of
> *Safe P.
> *Sent:* Friday, 20 November 2009 9:35 AM
> *To:* concurrency-interest at cs.oswego.edu
> *Subject:* [concurrency-interest] [CPU Affinity]
> ThreadPoolExecutor to improve"O.S Scheduler" ?
>
> Hi,
> I'm very new to concurrent programming and I couldn't find
> anywhere if this is an issue or just a limitation.
> I'm running several instances of a java process like "process.sh
> & process.sh & process.sh ..." in an HP-UX that runs over a
> 12-core machine.
>
> When I use sar, top, and other utilities I can see that HP-UX is
> using just 1 core. It doesn't manage to assign one processor per
> process.
> Can I get this using ThreadPoolExecutor (like one
> System.Runtime.exec() per thread)?
> Unfortunately, this machine is a production server so I can't
> get access to it in order to do some test and verify that, and
> of course, if this make a significant time improvement.
>
> Thank you very much in advanced.
> --Matias
>
>
> ------------------------------------------------------------------------
>
> Encontra las mejores recetas con Yahoo! Cocina.
> http://ar.mujer.yahoo.com/cocina/
>
>
> ------------------------------------------------------------------------
>
> Encontra las mejores recetas con Yahoo! Cocina.
> http://ar.mujer.yahoo.com/cocina/
>
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
From rsk at moocat.org Fri Nov 20 14:45:42 2009
From: rsk at moocat.org (R Samuel Klatchko)
Date: Fri, 20 Nov 2009 11:45:42 -0800
Subject: [concurrency-interest] [CPU Affinity] ThreadPoolExecutor to
improve"O.S Scheduler" ?
In-Reply-To: <761766.25527.qm@web111110.mail.gq1.yahoo.com>
References:
<761766.25527.qm@web111110.mail.gq1.yahoo.com>
Message-ID: <8eddd5030911201145l6a2c32acm34135b4202e817d7@mail.gmail.com>
Does this only happen with Java or does it happen with other processes as
well?
Try running multiple copies of some other long lived process and see if they
are all running on a single processor. If they are, you are running into an
issue with the OS (most likely a configuration limiting your user to a
single processor).
samuel
On Fri, Nov 20, 2009 at 11:35 AM, Safe P. wrote:
> David, thank you for your answer.
>
> The problem is exactly this:
>
> when I run java -cp . MyProcess & java -cp .MyProcess & ... in a 12-core
> machine that runs HP-UX, all processes are assign to one processor.
>
> That means that an instance must wait until the end of the previous
> instance to start. I want to run all instances in parallel, using all 12
> processors. Is this possibly? Maybe using ThreadPoolExecutor to execute each
> instance of this "java -cp .."?
>
> Thank you very much in advance!
>
>
> --- El *jue 19-nov-09, David Holmes * escribi?:
>
>
> De: David Holmes
> Asunto: RE: [concurrency-interest] [CPU Affinity] ThreadPoolExecutor to
> improve"O.S Scheduler" ?
> Para: "Safe P." , concurrency-interest at cs.oswego.edu
> Fecha: jueves, 19 de noviembre de 2009, 9:45 pm
>
> Matias,
>
> I'm not really understanding your problem/issue, but most systems have some
> notion of processing domains that let you allocate resources (memory and
> CPU) to a domain and then run specific processes in specific domains. On
> Solaris this is done with processor sets, while on Linux there are CPU-sets.
> I don't know what HP-UX has.
>
> There are no Java API's to control thread or process affinity (other than
> by exec'ing OS utilities to do it, or calling your own native code routines.
>
> Normally, absent any domains, all processes (and all their threads) can run
> on any available processor/core.
>
> HTH.
>
> David Holmes
>
> -----Original Message-----
> *From:* concurrency-interest-bounces at cs.oswego.edu [mailto:
> concurrency-interest-bounces at cs.oswego.edu]*On Behalf Of *Safe P.
> *Sent:* Friday, 20 November 2009 9:35 AM
> *To:* concurrency-interest at cs.oswego.edu
> *Subject:* [concurrency-interest] [CPU Affinity] ThreadPoolExecutor to
> improve"O.S Scheduler" ?
>
> Hi,
> I'm very new to concurrent programming and I couldn't find anywhere if this
> is an issue or just a limitation.
>
> I'm running several instances of a java process like "process.sh &
> process.sh & process.sh ..." in an HP-UX that runs over a 12-core machine.
>
> When I use sar, top, and other utilities I can see that HP-UX is using just
> 1 core. It doesn't manage to assign one processor per process.
>
> Can I get this using ThreadPoolExecutor (like one System.Runtime.exec() per
> thread)?
>
> Unfortunately, this machine is a production server so I can't get access to
> it in order to do some test and verify that, and of course, if this make a
> significant time improvement.
>
> Thank you very much in advanced.
> --Matias
>
> ------------------------------
>
> Encontra las mejores recetas con Yahoo! Cocina.
> http://ar.mujer.yahoo.com/cocina/
>
>
> ------------------------------
>
> Encontra las mejores recetas con Yahoo! Cocina.
> http://ar.mujer.yahoo.com/cocina/
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From normelton at gmail.com Sat Nov 21 22:54:15 2009
From: normelton at gmail.com (Norman Elton)
Date: Sat, 21 Nov 2009 22:54:15 -0500
Subject: [concurrency-interest] Concurrent Bidirectional Map
Message-ID: <6b3a7f010911211954q7f1a6155ka4cefceb9eaf963f@mail.gmail.com>
Let me start by saying that I am, by no means, a concurrency guru. But
I did have a use for a concurrent bidirectional map, one that
maintains key-to-value and value-to-key uniqueness. I whipped up a
quick implementation of ConcurrentBiMap built around two
ConcurrentHashMaps. The BiMap implements Map, with the single
extra method inverse(), which returns a Map.
I basically synchronized all the modifying methods (clear, put,
remove, etc) so that I could safely change both maps atomically. All
other methods are unsynchronized. The methods that would normally
return modifiable Sets (entrySet, values, keySet) return unmodifiable
versions of their "normal" values, since I have not yet come up with a
way to allow the user to atomically remove a value from such a set.
I'll attach both the code and a fairly extensive JUnit test case. A
few questions remain:
- Have I reinvented the wheel? Is there already a good / better
implementation of a ConcurrentBiMap?
- Is there a good way to test the atomicity of code? I could fire up
multiple threads and let them simultaneously hammer away at a shared
hash, but I'm not sure this would be a good reproducible test case.
- Can anyone think of a way to allow the three Set methods (entrySet,
keySet, values) to return modifiable values? That is, if you remove an
item from them, they atomically affect the original BiMap.
Thanks for any pointers,
Norman
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ConcurrentBiMap.java
Type: application/octet-stream
Size: 4630 bytes
Desc: not available
URL:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ConcurrentBiMapTests.java
Type: application/octet-stream
Size: 6561 bytes
Desc: not available
URL:
From dhanji at gmail.com Sat Nov 21 23:28:28 2009
From: dhanji at gmail.com (Dhanji R. Prasanna)
Date: Sun, 22 Nov 2009 15:28:28 +1100
Subject: [concurrency-interest] Concurrent Bidirectional Map
In-Reply-To: <6b3a7f010911211954q7f1a6155ka4cefceb9eaf963f@mail.gmail.com>
References: <6b3a7f010911211954q7f1a6155ka4cefceb9eaf963f@mail.gmail.com>
Message-ID:
Unfortunately, if you synchronize put() and remove() you lose the
concurrency benefits of CHM. All threads will serialize behind the put lock.
Also, in your implementation, in order for the bi-map-put to be perceived
atomically, you would have to synchronize the get method as well =(
It is an interesting use case, however.
my 2c.
Dhanji.
On Sun, Nov 22, 2009 at 2:54 PM, Norman Elton wrote:
> Let me start by saying that I am, by no means, a concurrency guru. But
> I did have a use for a concurrent bidirectional map, one that
> maintains key-to-value and value-to-key uniqueness. I whipped up a
> quick implementation of ConcurrentBiMap built around two
> ConcurrentHashMaps. The BiMap implements Map, with the single
> extra method inverse(), which returns a Map.
>
> I basically synchronized all the modifying methods (clear, put,
> remove, etc) so that I could safely change both maps atomically. All
> other methods are unsynchronized. The methods that would normally
> return modifiable Sets (entrySet, values, keySet) return unmodifiable
> versions of their "normal" values, since I have not yet come up with a
> way to allow the user to atomically remove a value from such a set.
>
> I'll attach both the code and a fairly extensive JUnit test case. A
> few questions remain:
>
> - Have I reinvented the wheel? Is there already a good / better
> implementation of a ConcurrentBiMap?
>
> - Is there a good way to test the atomicity of code? I could fire up
> multiple threads and let them simultaneously hammer away at a shared
> hash, but I'm not sure this would be a good reproducible test case.
>
> - Can anyone think of a way to allow the three Set methods (entrySet,
> keySet, values) to return modifiable values? That is, if you remove an
> item from them, they atomically affect the original BiMap.
>
> Thanks for any pointers,
>
> Norman
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From martinrb at google.com Sun Nov 22 12:36:25 2009
From: martinrb at google.com (Martin Buchholz)
Date: Sun, 22 Nov 2009 09:36:25 -0800
Subject: [concurrency-interest] park and unpark low-level details
In-Reply-To: <4B06E2EC.2050301@redhat.com>
References: <4B06D60C.2020005@redhat.com>
<3D323829-DF05-41EE-A5E2-B9311C02CEEE@sun.com>
<4B06E2EC.2050301@redhat.com>
Message-ID: <1ccfd1c10911220936i5ee476dt3c46fe1cfd4e3081@mail.gmail.com>
On Fri, Nov 20, 2009 at 10:41, Andrew Haley wrote:
> Dave Dice wrote:
>
> >> What do you man by this? I guess there's a nice way to map park and
> >> unpark onto low-level NPTL primitives (futexes, perhaps?) Did you
> >> have a sketch of a design for that?
> >
>
> > We preferred to use more standardized interfaces. I experimented
> > with using futexes instead of the usual condvar-mutex-flag tuple but
> > it wasn't particularly better.
>
> I'm not surprised. I did some profiling, and even with quite heavily
> contended locks the time spent in park and unpark is often down in
> the noise. Amazing, really. :-)
>
Coincidentally, there's an article on futexes here:
http://lwn.net/Articles/360699/
Regarding using standard interfaces:
---
Man pages: The current man pages do not include some of the new futex
operations. They suggest a policy for the value of the futex which has led
to some confusion regarding usage of futexes. Worst of all, the user space
futex() definition has been removed from /usr/include/linux/futex.h,
rendering the man pages not only incomplete, but also inaccurate. Users of
futexes must use the syscall interface directly.
---
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From normelton at gmail.com Sun Nov 22 14:54:28 2009
From: normelton at gmail.com (Norman Elton)
Date: Sun, 22 Nov 2009 14:54:28 -0500
Subject: [concurrency-interest] Concurrent Bidirectional Map
In-Reply-To:
References: <6b3a7f010911211954q7f1a6155ka4cefceb9eaf963f@mail.gmail.com>
Message-ID: <6b3a7f010911221154o216b6c4craa77f2fd52ec9f56@mail.gmail.com>
Dhanji,
Thanks for dedicating some brain-cells to looking at this.
> Unfortunately, if you synchronize put() and remove() you lose the
> concurrency benefits of CHM. All threads will serialize behind the put lock.
Yep. My application is 99% reads and 1% writes, so I can tolerate
single-threading put() and remove() operations. One major benefit that
does remain; however, is that I don't have to worry about concurrent
modification exceptions when iterating through the map members.
I would love someone with more concurrency kung-fu to implement a real
BiMap, so that I wouldn't have to rely on synchronization.
> Also, in your implementation, in order for the bi-map-put to be perceived
> atomically, you would have to synchronize the get method as well =(
This is where I'm a little perplexed. I've synchronized any write
methods, so that the two CHMs stay "in synch". Any read operations, as
I see it, should be safe to fall through to the primary CHM without
extra synchronization. If one thread is updating the map while another
is reading, the reading thread will either get the new or the old
value, but we shouldn't get any exceptions or end up with inconsistent
CHMs.
Or am I misunderstanding something?
Thanks again,
Norman
From davidcholmes at aapt.net.au Sun Nov 22 17:52:52 2009
From: davidcholmes at aapt.net.au (David Holmes)
Date: Mon, 23 Nov 2009 08:52:52 +1000
Subject: [concurrency-interest] Concurrent Bidirectional Map
In-Reply-To: <6b3a7f010911221154o216b6c4craa77f2fd52ec9f56@mail.gmail.com>
Message-ID:
Norman,
Norman Elton writes:
> Dhanji R. Prasanna writes:
> > Also, in your implementation, in order for the bi-map-put to be
> > perceived atomically, you would have to synchronize the get
> > method as well =(
>
> This is where I'm a little perplexed. I've synchronized any write
> methods, so that the two CHMs stay "in synch". Any read operations, as
> I see it, should be safe to fall through to the primary CHM without
> extra synchronization. If one thread is updating the map while another
> is reading, the reading thread will either get the new or the old
> value, but we shouldn't get any exceptions or end up with inconsistent
> CHMs.
>
> Or am I misunderstanding something?
Your reader thread can access the map while only one of the associations is
in effect. Whether that can cause a problem in practice depends on the exact
semantics of the bi-map and how it is used. If you add the value->key
mapping before the key->value mapping (and remove in opposite order) then it
will mitigate the ability to see inconsistency - assuming you always lookup
by key, not value.
David Holmes
> Thanks again,
>
> Norman
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
From jed at atlassian.com Sun Nov 22 18:40:04 2009
From: jed at atlassian.com (Jed Wesley-Smith)
Date: Mon, 23 Nov 2009 10:40:04 +1100
Subject: [concurrency-interest] Concurrent Bidirectional Map
In-Reply-To: <6b3a7f010911221154o216b6c4craa77f2fd52ec9f56@mail.gmail.com>
References: <6b3a7f010911211954q7f1a6155ka4cefceb9eaf963f@mail.gmail.com>
<6b3a7f010911221154o216b6c4craa77f2fd52ec9f56@mail.gmail.com>
Message-ID: <4B09CBD4.6000707@atlassian.com>
Norman,
I have found that for this kind of application (read-mostly) a
copy-on-write approach can work very well (depending on the size of the
structure as the write is O(n)). We use a CopyOnWriteMap[1] that follows
a similar scheme to the j.u.c CopyOnWriteArrayList and have found that
its read performance in highly contended reads is excellent as it is
completely lock-free, whereas CHM will still do some locking on its
internal buckets.
Implementing something similar for google-collections BiMap would not be
difficult (the algorithm is very simple), the only problem being that
the g.c. Immutable*.Builder implementations don't support removal[2]
unfortunately, making a COW* implementation that uses them internally
require two copies per write in the remove/replace cases.
cheers,
jed.
[1]
https://labs.atlassian.com/source/browse/CONCURRENT/trunk/src/main/java/com/atlassian/util/concurrent/CopyOnWriteMap.java?r=2602
[2] http://code.google.com/p/google-collections/issues/detail?id=279
Norman Elton wrote:
> Dhanji,
>
> Thanks for dedicating some brain-cells to looking at this.
>
>
>> Unfortunately, if you synchronize put() and remove() you lose the
>> concurrency benefits of CHM. All threads will serialize behind the put lock.
>>
>
> Yep. My application is 99% reads and 1% writes, so I can tolerate
> single-threading put() and remove() operations. One major benefit that
> does remain; however, is that I don't have to worry about concurrent
> modification exceptions when iterating through the map members.
>
> I would love someone with more concurrency kung-fu to implement a real
> BiMap, so that I wouldn't have to rely on synchronization.
>
>
>> Also, in your implementation, in order for the bi-map-put to be perceived
>> atomically, you would have to synchronize the get method as well =(
>>
>
> This is where I'm a little perplexed. I've synchronized any write
> methods, so that the two CHMs stay "in synch". Any read operations, as
> I see it, should be safe to fall through to the primary CHM without
> extra synchronization. If one thread is updating the map while another
> is reading, the reading thread will either get the new or the old
> value, but we shouldn't get any exceptions or end up with inconsistent
> CHMs.
>
> Or am I misunderstanding something?
>
> Thanks again,
>
> Norman
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
From dhanji at gmail.com Sun Nov 22 18:11:57 2009
From: dhanji at gmail.com (Dhanji R. Prasanna)
Date: Sun, 22 Nov 2009 15:11:57 -0800
Subject: [concurrency-interest] Concurrent Bidirectional Map
In-Reply-To:
References: <6b3a7f010911221154o216b6c4craa77f2fd52ec9f56@mail.gmail.com>
Message-ID:
On Sun, Nov 22, 2009 at 2:52 PM, David Holmes wrote:
> Norman,
>
> Norman Elton writes:
> > Dhanji R. Prasanna writes:
> > > Also, in your implementation, in order for the bi-map-put to be
> > > perceived atomically, you would have to synchronize the get
> > > method as well =(
> >
> > This is where I'm a little perplexed. I've synchronized any write
> > methods, so that the two CHMs stay "in synch". Any read operations, as
> > I see it, should be safe to fall through to the primary CHM without
> > extra synchronization. If one thread is updating the map while another
> > is reading, the reading thread will either get the new or the old
> > value, but we shouldn't get any exceptions or end up with inconsistent
> > CHMs.
> >
> > Or am I misunderstanding something?
>
> Your reader thread can access the map while only one of the associations is
> in effect.
>
Yea, the update to both maps is not atomic because reader threads can
interleave between writes to either map. Technically, you won't corrupt the
map (unlike in the case of a regular HashMap), but that depends on what your
definition of corruption is (as David says). A read from the value->key map
can be inconsistent with a put to the key->value map.
Dhanji.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From normelton at gmail.com Sun Nov 22 20:19:18 2009
From: normelton at gmail.com (Norman Elton)
Date: Sun, 22 Nov 2009 20:19:18 -0500
Subject: [concurrency-interest] Concurrent Bidirectional Map
In-Reply-To:
References: <6b3a7f010911221154o216b6c4craa77f2fd52ec9f56@mail.gmail.com>
Message-ID: <6b3a7f010911221719s7271de1fx74206f8a9b2f705@mail.gmail.com>
> Yea, the update to both maps is not atomic because reader threads can
> interleave between writes to either map. Technically, you won't corrupt the
> map (unlike in the case of a regular HashMap), but that depends on what your
> definition of corruption is (as David says). A read from the value->key map
> can be inconsistent with a put to the key->value map.
Thanks David & Dhanji for your thinking on this.
I realize that if two threads hit the map at the same time, one doing
a look-by-key and another doing a lookup-by-value, while a third
thread is doing an update, it is possible the two readers will see
different pairings. But, is this a problem? They are two separate
threads. How should they expect to be simultaneously seeing the same
"state" of the map?
Likewise, a single thread that does a lookup-by-key, followed by a
lookup-by-value, should expect to get two different results, since
it's entirely feasible that another thread updates the map between the
two reads.
My implementation of the BiMap doesn't have any unsynchronized methods
(I think!) that refer to both maps. All of the reader methods use a
single of the two CHMs, which represent a valid "snapshot" of the map
when referenced.
Thanks again, all, for your help on this! Let me know if my reasoning
is flawed, I've enjoyed thinking though this :-).
Norman
From davidcholmes at aapt.net.au Sun Nov 22 20:30:29 2009
From: davidcholmes at aapt.net.au (David Holmes)
Date: Mon, 23 Nov 2009 11:30:29 +1000
Subject: [concurrency-interest] Concurrent Bidirectional Map
In-Reply-To: <6b3a7f010911221719s7271de1fx74206f8a9b2f705@mail.gmail.com>
Message-ID:
Norman,
>From how you describe it, it sounds like there is no consistency issue. If
no thread can ever expect to find that:
v->k => k->v
then the fact that the above can fail to hold during a modification to the
bi-map seems of little consequence.
Cheers,
David
> -----Original Message-----
> From: concurrency-interest-bounces at cs.oswego.edu
> [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Norman
> Elton
> Sent: Monday, 23 November 2009 11:19 AM
> To: concurrency-interest at cs.oswego.edu
> Subject: Re: [concurrency-interest] Concurrent Bidirectional Map
>
>
> > Yea, the update to both maps is not atomic because reader threads can
> > interleave between writes to either map. Technically, you won't
> corrupt the
> > map (unlike in the case of a regular HashMap), but that depends
> on what your
> > definition of corruption is (as David says). A read from the
> value->key map
> > can be inconsistent with a put to the key->value map.
>
> Thanks David & Dhanji for your thinking on this.
>
> I realize that if two threads hit the map at the same time, one doing
> a look-by-key and another doing a lookup-by-value, while a third
> thread is doing an update, it is possible the two readers will see
> different pairings. But, is this a problem? They are two separate
> threads. How should they expect to be simultaneously seeing the same
> "state" of the map?
>
> Likewise, a single thread that does a lookup-by-key, followed by a
> lookup-by-value, should expect to get two different results, since
> it's entirely feasible that another thread updates the map between the
> two reads.
>
> My implementation of the BiMap doesn't have any unsynchronized methods
> (I think!) that refer to both maps. All of the reader methods use a
> single of the two CHMs, which represent a valid "snapshot" of the map
> when referenced.
>
> Thanks again, all, for your help on this! Let me know if my reasoning
> is flawed, I've enjoyed thinking though this :-).
>
> Norman
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest