Broken thread scheduling in indexed loop (missing safepoint?)
Vitaly Davidovich
vitalyd at gmail.com
Fri Nov 30 16:03:26 PST 2012
I see, thanks Vladimir.
Sent from my phone
On Nov 30, 2012 6:53 PM, "Vladimir Kozlov" <Vladimir.Kozlov at oracle.com>
wrote:
> On 11/30/12 15:37, Vitaly Davidovich wrote:
>
>> What's the reason safepoints were yanked out in the first place? I'd
>> assume safepoints aren't that frequent, at least while a typical loop is
>> running. Once the polling page is in cache (first iteration will bring
>> it in) and assuming the test instruction on it will always go the same
>> way (i.e. safepoint not requested) won't the cache hitting load and
>> perfectly predicted (common case) branch not have noticeable impact on
>> the loop? Or am I underestimating safepoint frequency? Or is the polling
>> test in the loop inhibiting some optimizations due to control flow? Or
>> something else? :)
>>
>
> It is not simple touch of polling page. It is point where a method could
> be deoptimized. For that a SafePoint node has edges to live values in a
> graph (C2 IR). And it affects our current implementation of loop
> optimizations (unrolling, iterations splitting, vectorization). So C2 will
> generate less optimal loop code.
>
>
>> Also, counted loops are only those with a compile time constant limit,
>> right? Or does a read of a final field (or otherwise deduced by JIT to
>> be a runtime constant) whose value is the loop limit also count?
>>
>
> No. Counted loop in C2 is a loop with constant integer increment, one
> entry path and one exit path with iteration check at the end of loop's
> body. Low and upper iterations limits could be variables.
>
> Vladimir
>
>
>> Thanks
>>
>> Sent from my phone
>>
>> On Nov 30, 2012 6:19 PM, "Vladimir Kozlov" <Vladimir.Kozlov at oracle.com
>> <mailto:Vladimir.Kozlov@**oracle.com <Vladimir.Kozlov at oracle.com>>>
>> wrote:
>>
>> On 11/30/12 12:51, Vitaly Davidovich wrote:
>>
>> By the way, what would a fix involve? Polling for safepoint every
>> X
>> trips through the loop where X is some reasonable value and then
>> overridable via a JVM arg? I guess otherwise the JVM would have to
>> know/estimate the cost of the loop body, which seems intractable
>> in general.
>>
>>
>> An other approach is "mine stripping" - split a loop into inner and
>> outer loops.
>> Polling not on each iteration requires test and branch which could
>> be more expensive than load with unused result.
>> Current plan (6869327) is simple to keep safepoint in counted loop
>> when the flag is specified.
>>
>> Vladimir
>>
>>
>> What does J9 do? Does it simply not strip out polling?
>>
>> Thanks
>>
>> Sent from my phone
>>
>> On Nov 30, 2012 3:28 PM, "Volker Simonis"
>> <volker.simonis at gmail.com <mailto:volker.simonis at gmail.**com<volker.simonis at gmail.com>
>> >
>> <mailto:volker.simonis at gmail._**_com
>> <mailto:volker.simonis at gmail.**com <volker.simonis at gmail.com>>>>
>> wrote:
>>
>> Hi Vitaly,
>>
>> you're right, even a STW GC will have to wait until this loop
>> without a safepoint will finish. On the other side, if
>> there is an
>> allocation inside the loop, the allocation will be done on
>> the "fast
>> path" (without safepoint check) only until the thread local
>> buffer
>> (TLAB) will be full. After that it will have to take the
>> "slow path"
>> which is a VM call and which has a safe point check. So in
>> practice
>> I think the problem is only with very tight loops which do
>> same
>> small but expensive computations (or with nested int loops
>> which
>> have potentially the same complexity like long loops but no
>> safpoint
>> either).
>>
>> Regards,
>> Volker
>>
>> On Friday, November 30, 2012, Vitaly Davidovich wrote:
>>
>> Hi Volker,
>>
>> Just curious - what happens if a STW GC needs to occur
>> right as
>> this type of loop is entered? Does the VM just stall
>> until the
>> loop exits? What if this loop does a fast path
>> allocation on
>> some iteration? Do all allocations check for safepoints
>> internally?
>>
>> Thanks
>>
>> Sent from my phone
>>
>> On Nov 30, 2012 1:41 PM, "Volker Simonis"
>> <volker.simonis at gmail.com <mailto:volker.simonis at gmail.**com<volker.simonis at gmail.com>>>
>> wrote:
>>
>> Hi,
>>
>> This is a long standing problem of HotSpot
>> (compared for
>> example to
>> J9). It doesn't put Safepoints into counted int loops
>> (because it
>> assumes they will terminate just "fast enough"
>> which is not
>> the case
>> in your example). You can see another example for
>> this
>> behavior in
>> these slides
>> "http://www.progdoc.de/papers/**__Jax2012/jax2012.html#%288%29<http://www.progdoc.de/papers/__Jax2012/jax2012.html#%288%29>
>> <http://www.progdoc.de/papers/**Jax2012/jax2012.html#%288%29<http://www.progdoc.de/papers/Jax2012/jax2012.html#%288%29>
>> >"
>> together with the generated assembler code.
>>
>> You can easily solve the problem by making your loop
>> variable a "long"
>> instead of an "int". In that case, HotSpot will be
>> more
>> cautious and
>> place a safepoint into the loop.
>>
>> Regards,
>> Volker
>>
>> On Fri, Nov 30, 2012 at 2:05 PM, Alexey Goncharuk
>> <agoncharuk at gridgain.com <mailto:agoncharuk at gridgain.**com<agoncharuk at gridgain.com>>>
>> wrote:
>> > Hi,
>> >
>> > We faced some weird issue with thread scheduling. At a
>> first glance it
>> > looked like it relates to
>> >
>> http://bugs.sun.com/__**bugdatabase/view_bug.do?bug___**
>> id=7160161<http://bugs.sun.com/__bugdatabase/view_bug.do?bug___id=7160161>
>> <http://bugs.sun.com/**bugdatabase/view_bug.do?bug_**id=7160161<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7160161>
>> >
>> but not exactly.
>> >
>> > This is the code we ran:
>> >
>> > public static void main(String[] args) throws Exception {
>> Thread worker =
>> > new Thread() { @Override public void run() { double d =
>> 0; for (int j = 1; j
>> > < 2000000000; j++) d += Math.log(Math.E * j);
>> System.out.println(d); } };
>> > Thread reporter = new Thread() { @Override public void
>> run() { try { while
>> > (true) { Thread.sleep(1000); System.out.println("Running: " +
>> > System.currentTimeMillis()); } } catch
>> (InterruptedException ignored) {
>> > Thread.currentThread().__**interrupt(); } } };
>> reporter.start(); worker.start();
>> > worker.join(); reporter.interrupt(); }
>> >
>> > One can expect that printing thread would output messages
>> during all the
>> > calculation time, however it hangs after 3-4 iterations.
>> Setting
>> > -XX:FreqInlineSize=0 as described in original bug report
>> does not help in
>> > this case, but if I extract loop body into a separate
>> method, setting this
>> > option works. Example passes with -Xint option as well.
>> (Tested with
>> > 1.6.0_33, 1.6.0_37, 1.7.0_07 on Windows and 1.6.0_33 on
>> Linux)
>> >
>> > I saw #7160161 marked as resolved, so I just wanted to
>> confirm if behavior
>> > we see really relates to this issue and it was fixed (bug
>> report covers
>> > non-Counted loop only).
>> >
>> > Also, is there any other workarounds rather then
>> extracting the method and
>> > specifying FreqInlineSize=0?
>> >
>> > Thanks,
>> > Alexey Goncharuk
>> >
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20121130/e8dce5cb/attachment-0001.html
More information about the hotspot-compiler-dev
mailing list