5 ms·
Not a new kind of issue, and not a problem IMHO. Some GCs need to reach a safepoint before doing their work; and when a classic Thread is chugging along in a t
by BenoitP 4y ago
Not a new kind of issue, and not a problem IMHO.
Some GCs need to reach a safepoint before doing their work; and when a classic Thread is chugging along in a tight loop, that thread is blocking the whole system for a pending GC.
One hacky fix is to provide an opportunity for a safepoint (System.out.print every 10k iterations). Other tools like JVM command line options allow for observing safepoint triggering.
The same goes for virtual threads: inserting a Thread.sleep(1L) every nth iteration of a tight loop does it.
Also there was talk specifying a custom scheduler for the virtual threads. That would not help in inserting switching opportunities, but it would give a way to define what kind of fairness you want.
- test-account 4y agoAgree. Let's document this trick and I'm happy with that unfair scheduling inconvenience for CPU heavy operations.
- deleted 4y ago[deleted]
- topspin 4y agoSeconded. Although I think Thread::yield should do what it says on the tin in the case of lightweight threads and it's hard to understand why they chose to not make it so, I don't care much. If the only problem I have to anticipate to get the full benefit of a well behaved lightweight threat scheduling is strategically sprinkling yield points inside those few tight loops that might actually threaten to hog a core then it's a net win.
- anonymousDan 4y agoHaving to do it manually is tedious and error prone IMHO. Better to have a reasonably good automated mechanism that you can disable if you wish).
- topspin 4y ago> tedious and error prone IMHO It's neither. The frequency of non-blocking CPU bound sections of most applications is low and so the need to introduce scheduling hints is also infrequent. Aside from an endless, non-blocking loop that never yields omitting possibly beneficial yield points isn't an error; scheduling will not be ideal but the process will ultimately produce the same result.
- topspin 4y agoThinking about this further, a pragmatic enhancement to Thread::yield might look like this: enum Hint { ALWAYS, FREQUENT, SOMETIMES, INFREQUENT, NEVER } Thread::yield(Hint); The method could be intrinsic to the compiler+runtime to provide runtime optimization (loop unrolling, tuning, etc.) of the 2nd - 4th cases. This would neatly avoid the need to: long n = 0; while (true) { // stuff if (++n > SOME_LIMIT) { n = 0; // yield here } } ... or similar.
- anonymousDan 4y agoSeems like safepoints are an ideal way to do this. It sounds similar in ways to how the BEAM runtime for Elixir/Erlang will count reductions and preempts a lightweight process. I guess the interesting question is whether the same safepoint testing mechanism can be reused directly or whether some more complex logic is required on the critical path
- samsquire 4y agoPutting an if statement in your loops shall slow down your loops. Instead chunk/partition the loop and run it in chunks.