Question about Linker.Option.isTrivial()
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Jan 12 17:03:02 UTC 2024
On 12/01/2024 16:28, 刘希晨 wrote:
> Hi I want to ask a question about using project-panama, I implemented
> a network library using JDK21 with panama-foreign and the performance
> are quite well, since the API will officially release in JDK22, I
> started to migrating my project to using JDK22-ea, and I have a
> question about using Linker.Option.isTrivial(), I noticed that in
> JDK22 it seems to be renamed as Linker.Option.critical(), the javadoc
> says the function should have an extremely short running time in all
> cases, and does not callback into Java. I am pretty sure that it could
> be used on some functions returning constants macro from C, but in
> some cases, I am not quite sure if this option could be used, here are
> some examples:
It's hard to define a clear boundary - the thing to keep in mind is that
critical() disables GC while the call is active - so you don't want to
run it for a very long time. But if you understand the consequences, you
might be in a better position to judge if that's ok.
>
> 1. calling malloc() and free(), or some other API like epoll_create()
> and epoll_ctl()
malloc and free definitively (and I used that in the past - I think the
current implementation of Arena::allocate also skips the transition, so
effectively it's as if it were using that option). I'm less sure about
the others, as I'm not too familiar with them.
> 2. calling send() and recv() on non-blocking sockets
That should be ok (because of the non-blocking nature)
> 3. just assigning some values to the target structs in C functions
Definitively - that's, one might argue, one of the things critical() is
designed for.
>
> They all have a very short running time, and they do not callback into
> Java, I have tested using Linker.Option.isTrivial() and they all went
> well, but I am still not very sure about my usage here, since I don't
> quite understand what Linker.Option.isTrivial() did under the hood, so
> I want to seek some suggestions from experts here.
I believe you are good. As I said, the main thing is that code in
critical state never safepoints, so GC can't run while you are in
critical native. But if you used that option in few places, and you
noticed no degradation of GC performance, then I think you are good.
That said... in many cases and benchmarks I made, I could not see a big
difference between critical and non-critical. It is really good for
short-lived calls (e.g. ~10ns), but if you call heavier stuff it gets in
the noise pretty rapidly (e.g. from 25ns onwards). Typically it amounts
to 4-5ns of savings, which might not make a difference at all in the big
picture.
The new flavor of critical available in 22, on the other hand (which
allows you to pass pinned heap segments as well) is much more powerful,
as it allows you to omit memory copy in some cases. So, typically, the
advantages of using that mode tend to scale more even as the cost of the
called function goes up.
Maurizio
More information about the panama-dev
mailing list