Efficiency: Let thread do other tasks as long encoder/decoder is busy#215
Conversation
|
@mkarg There are test failures. |
|
Thread#yield has been notorious, at least what I have observed working on multiple different CPU architectures. I wonder if we should rather use a |
I cannot second that, and it should not be necessary to synchronize (and it would uselessly cost resources), as all what we want solely is exactly what Thread.yield() claims to do: Let the thread do other work (not block it). What is the actual problem facing here? If needed I can discuss with OpenJDK team (NB: I am an OpenJDK contributor) to see what the cause is. Edit: Just thinking out loudly: Maybe we like to add |
Sorry for this. There was a typo. Fixed that. Please re-run the tests. NB: In fact, it was not a test failure but a compilation failure. |
|
I'd suggest talking to someone in OpenJDK because ARM behaves differently with this. We can keep |
Can you post your concerns / experience with arm wrt yield? So we understand better what to talk about. |
True async sounds great, but is this supported by the invoked classes? If so, it would be much better than busy wait (with or without yield / parkNanos)! 🤩 |
|
JDK Thread#yield can be ignored by the OS scheduler as per the doc, and it will most likely happen with ARM v7, although most v7s have a PAUSE instruction set. Sure, it can happen with x86, but ARM is something I never use, so people using Brotli4j on those CPUs are most likely to notice. OpenJDK contributors working with ARM will have the best answer to this. Although it's very much CPU-dependent as well. True async is the way to go, it's a JNI call, so we have to wrap the blocking call behind the scenes. I'd prefer a new class in a dedicated "async" package for this. But you get the idea. This way, it fits better for async libraries or applications relying on native async support from Brotli4j. |
|
Sure, async is the best option. Speaking of yield, I still do not see the problem. In x86 yield will yield, while on arm it will be a no-op. A no-op cannot be worse than what we have today. So my contribution should not improse any problems other than most likely be useless on arm. |
|
Agreed. Curiously enough, what will the cost of |
|
When yield is a no-op (like assumed on arm), the costs for the JVM is literally zero, as due to the missing implementation the HotSpot compiler simply removes the call completely. Implementing async is a great idea, but should go in a separate PR. |
|
Indeed, |
|
Thanks a lot! :) |
Actually I have no found a way for async, as |
|
Yes, native code does not support that. Our best bet is to go with an async wrapper because writing async from the ground up will be challenging. We can always later implement native async without breaking Java APIs. |
Motivation:
Busy loops are blocking valuable threads, so other tasks are blocked while the current task spins waiting. This reduces concurrency without a need, hence makes inefficient use of the existing hardware.
Modification:
Using
Thread.yield()in all busy waiting loops.Result:
Other tasks are allowed to run while encode / decoder is busy.