Sending interrupts to the worker threads upon teardown
Chris Vest
mr.chrisvest at gmail.com
Mon Apr 14 18:56:10 UTC 2014
On 14 Apr 2014, at 19:27, Aleksey Shipilev <aleksey.shipilev at oracle.com> wrote:
> Result measurementLoop(...) {
> long ops = 0;
> long time1 = System.nanoTime();
> while(!isDone) {
> try {
> testTake();
> // place the ops++ here?
> } catch (InterruptedException e) {
> break;
> }
> // or, place the ops++ here?
> }
> long time2 = System.nanoTime();
> return new Result(ops, time2 - time1);
> }
>
> Both cases are wrong: putting ops++ in the try-catch block
> underestimates ops (misses the short-circuited one), putting ops++ after
> the try-catch block overestimates ops (includes short-circuited one in
> the time measurement).
>
> Moreover, considering that the interrupted return is probably for the
> test method which had stuck, our timing measurement is already wrong. We
> can allow this only in SampleTime, which samples the individual
> execution times, but that seems too stifling.
>
> Or, we can blindly deliver the interrupts knowing that people relying on
> this have no reason to believe the performance numbers.
>
> Thoughts?
Yeah… both are wrong. And there is no way for the harness to know how much work did or did not get done, or how much time was spent blocking. I was guessing that the synchronised iterations would magically take care of and exclude these kinds of outliers at the beginnings and the ends from the measurement, but I guess that was a misconception?
>
> -Aleksey.
>
> P.S. While writing this up, it occurred to me that we can dodge the
> entire interruption thing by specifying the order in which @GMB methods
> in asymmetric benchmark should leave the measurement. In Chris' example
> we should keep putter thread in measurement until taker leaves without
> blocking. Hm... Maybe that makes Control redundant?
Well, they say fortune favours the bold, so… https://gist.github.com/chrisvest/10672412 — but then again, hacks like that are a bit too bold, even for me :)
I’m not sure just specifying the order in which the threads leaves the measurement is enough. In the case of SynchronousQueue, put() will block if there is already an item enqueued. So when the taker leaves, the putting thread has to stop before it can do two puts in a row.
Cheers,
Chris
More information about the jmh-dev
mailing list