10 ms·
I think this is an enormously bad idea. The whole point of using sun.misc.Unsafe is because you need to do something with basically no overhead, regardless of s
by slaymaker1907 3y ago
I think this is an enormously bad idea. The whole point of using sun.misc.Unsafe is because you need to do something with basically no overhead, regardless of safety. In my opinion, they should just modularize it such that users must enable access to it explicitly. The MemorySegment API is nice, but sometimes you really want to skip bounds checking in a cross platform way.
- throwaway2037 3y agoDid you read the JEP? << Over the past several years, we have introduced two standard APIs that are safe and performant replacements for the memory-access methods in sun.misc.Unsafe: java.lang.invoke.VarHandle, introduced in JDK 9, provides methods to safely and efficiently manipulate on-heap memory: fields of objects, static fields of classes, and elements of arrays. java.lang.foreign.MemorySegment, introduced in JDK 22, provides methods to safely and efficiently access off-heap memory (sometimes in cooperation with VarHandle). These standard APIs guarantee no undefined behavior, promise long-term stability, and have high-quality integration with the tooling and documentation of the Java Platform (examples of their use are given below). Given the availability of these APIs, it is now appropriate to deprecate and eventually remove the memory-access methods in sun.misc.Unsafe. >>
- bremac 3y agoAs the comment you replied to indicates, both of those APIs perform bounds-checking. In certain tight loops, this can add up to quite a bit of overhead [1]. However, it's not documented, but if you really know what you are doing you can convince the JIT to elide the bounds checks for MemorySegments [2]. [1] https://mail.openjdk.org/pipermail/panama-dev/2023-July/019363.html https://mail.openjdk.org/pipermail/panama-dev/2023-July/0193... [2] https://mail.openjdk.org/pipermail/panama-dev/2023-July/019487.html https://mail.openjdk.org/pipermail/panama-dev/2023-July/0194...
- kaba0 3y agoAs pron mentioned, you can use the internal unsafe API without bound checks, you just need a flag for that
- grishka 3y agoIf you really insist on shooting yourself in the foot, you can do MemorySegment.ofAddress(0).reinterpret(Long.MAX_VALUE) to obtain a MemorySegment for the lower half of the address space of your process. Obviously, you set the address to Long.MAX_VALUE for the upper half.
- bremac 3y agoUnfortunately, unless the JIT can prove that the address you are accessing via the segment is non-negative, it can't elide the bounds check. See https://mail.openjdk.org/pipermail/panama-dev/2023-July/019478.html https://mail.openjdk.org/pipermail/panama-dev/2023-July/0194... for a bit more information.
- synthetigram 3y agoYou might be correct, but it's not obvious to me unsafe is really faster. I recall reading that using unsafe invalidates most of the other optimizations because it's opaque to the JIT what you are doing. Also, if there are BCE opportunities, I feel pretty confident OpenJDK will add them, rather than being unsympathetic.
- iscoelho 3y agoAs the parent comment said: bounds checks. Unsafe is an order of magnitude faster for performance sensitive tasks due to only that. Quick publication showing the difference (up to 125%!): https://www2.cs.arizona.edu/~dkl/Publications/Papers/ics.pdf https://www2.cs.arizona.edu/~dkl/Publications/Papers/ics.pdf (and no, the story hasn't changed an awful lot since 2004. The gap still exists.)
- cogman10 3y ago> the story hasn't changed an awful lot since 2004 Um... yeah it has. For starters, hotspot wasn't even a part of the JVM at that point. But further newer JVM additions like the enhanced for loop eliminate a ton of conditions where someone would run into bounds checking. Doing a naked `a[i]` is simply not common java code. The JVM is far more likely today to remove the bounds check all together than it ever was in 2004.
- pron 3y agoThe cost of bounds checks, which is already low, could be reduced further the vast majority of uses with even more enhancements to the compiler's inlining decisions, so we're talking about an API whose value is already small and constantly declining. However, those who think they absolutely need to avoid bounds checks could, indeed, use a flag to access the JDK's internals. We don't think that such a small benefit (especially when integrated over all users) merits a supported API.
- iscoelho 3y ago> "which is already low", "such a small benefit" This is subjective. In my opinion, even 10%~ is massive. Performance matters and this would be a step backwards.
- kaba0 3y agoWhere it matters, you can just write that part in a low-level language and call out to that.
- yjftsjthsd-h 3y agoThus bringing us back to the same unsafety with extra steps and glue required; what did we gain from this? Edit: Unless you FFI to Rust / Ada / formally verified C, in which case perhaps we can claw back the performance and safety at the cost of a lot more dev work.
- eptcyka 3y agoFFI boundaries are inherently unsafe regardless of language.
- kaba0 3y agoBut more “distance” between the two might be better, like, copying some value-like objects and doing the operation on that and copying back the result is much safer, than passing pointers between the two worlds. And this change might push the balance a bit to this side.
- MrBuddyCasino 3y ago> sometimes you really want to skip bounds checking in a cross platform way What is a use case where this is crucial? Where the difference is not just to win a benchmark pissing contest, but where the delta is so large that it is a factor of the JVM being a valid platform or not, and where the JVM would still be the best overall solution? Put differently: if you need extreme performance and full low-level control, what is a scenario where you still choose the JVM over eg Rust, and where bounds-checking elimination would be the deciding factor?