[concurrency-interest] Measuring and expressing contention

Chris Vest mr.chrisvest at gmail.com
Mon Jul 21 03:51:50 EDT 2014

What I forgot to mention was, that I have a background thread that continuously do odd jobs, such as allocation objects for the pool. I could use use LongAdders to submit wait times, and the number of waits, to this background thread. If this thread keeps fields that trail the sums of the LongAdders, I’ll be able to get deltas of how they grow over time:

long waitTimeSum = waitTimeSumAdder.sum();
long waitersSum = waitersSumAdder.sum();
long waitTimeForThisIteration = waitTimeSum - waitTimeSumField;
long waitersForThisIteration = waitersSum - waitersSumField;
waitTimeSumField = waitTimeSum;
waitersSumField = waitersSum;

This is racy, but that’s fine, since we’re only going to compute a rough indicator value anyway. I’m not quite sure in what way, but it seems important to distinguish between 10 waits of 100 ms each, and one wait of one second. In the latter case, a larger pause is caused by the contention on the pool, though I cannot know if the 10 waits of 100 ms were all part of the same web request, for instance. Computing the “rough average” (because race) would give me that, but then I wouldn’t be able to distinguish between one wait of 100 ms and 10 waits of 100 ms, which sounds like a reasonable thing to do. In any case, this background thread got more time to think about this, and could take note of how long ago it last checked those LongAdder sums, and then compute the decay based on time.

In the end, a number will be computed, but I’m still not sure what number would be meaningful to compute.


On 21 Jul 2014, at 04:15, Aaron Grunthal <aaron.grunthal at infinite-source.de> wrote:

> Have you tried the java.util.concurrent.atomic.LongAdder? It's designed for statistics-keeping in situations where CAS on a single shared cache-line causes too much contention.
> And you should make sure your benchmarking is realistic, the CAS may be expensive when it dominates your benchmark but could become significantly less contended when some actual work is performed between checking out objects from the pool and returning them.
> On 20.07.2014 12:48, Chris Vest wrote:
>> Hi fellas,
>> I’m building an object pool (for fun, mostly) that one configures with
>> an upper bound of how many objects it may contain, which means it can
>> become a source of contention when the demand for the pooled objects is
>> greater than the supply. In my implementation, this will effectively
>> boil down to threads waiting on BlockingQueue.poll(timeout, unit) calls.
>> I’m trying to come up with a good way to express the “current level of
>> contention” to the outside world, whatever that means. Basically, I want
>> to be able to tell an ops person that maybe the pool size has been
>> configured too small, but I’m coming up short with ideas of how to do
>> that without significant overhead. As for overhead, adding a CAS in the
>> fast-path would reduce the throughput by about 30%, which is too much,
>> but a CAS in the slowest-path case where the thread is going to block
>> anyway would be perfectly fine.
>> So, do you have any experience with solving something like this, or
>> ideas for how to approach it?
>> Cheers,
>> Chris
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> _______________________________________________
> 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: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20140721/ce95f36d/attachment.html>

More information about the Concurrency-interest mailing list