On Wed, 13 Aug 2025 14:18:42 GMT, Emanuel Peter <epe...@openjdk.org> wrote:
>> If I see this right, it could be that we duplicate the copy on a byte. If we >> only copy 2 bytes, then the copy on the second byte is repeated: >> >> src[0] -> dst[0] >> src[1] -> dst[1] >> src[1] -> dst[1] >> >> But is that ok? >> >> Assume we have threads 1 and 2, both access memory locations A and B: >> >> // Initial state >> A = x; >> B = y; >> >> // Concurrently: >> 1: B = A; >> 2: A = B + 1; >> >> What states could be observed at the end? We could look at all permutations >> of the 4 operations from threads 1 and 2. Let's call the operations 1.1 (1 >> loads A), 1.2 (1 stores B), 2.1 (2 loads B), 2.2 (2 stores A). >> These are the 4! / 4 = 6 possible permutations, together with the results >> for A and B: >> >> 1.1 1.2 2.1 2.2 -> A = x+1; B = x >> 1.1 2.1 1.2 2.2 -> A = y+1; B = x >> 1.1 2.1 2.2 1.2 -> A = y+1; B = x >> 2.1 1.1 1.2 2.2 -> A = y+1; B = x >> 2.1 1.1 2.2 1.2 -> A = y+1; B = x >> 2.1 2.2 1.1 1.2 -> A = y+1; B = y+1 >> >> Now assume we repeat the copy for thread 1. Thus, this could happen: >> >> 1: B = A; >> 2: A = B + 1; >> 1: B = A; // repeated copy >> >> And if it happens in this sequence, we get result: >> `A = x+1; B = x+1` >> But this result was not observable before. >> >> That makes me wonder if repeating the copy is really allowed in the Java >> memory model? > >> We have discussed the possibility of threads seeing different values, like >> in the above example by @eme64. We think this is ok because there are no >> guarantees of inter-thread visibility for memory segments. This has to be >> provided externally (e.g., using volatile/CAS operations). There are other >> cases where we are susceptible to similar problems (e.g, when doing >> unaligned long access). In short, segments do not fulfill all the aspects of >> the normal Java memory model (like for arrays). > > Hmm, I see. Is this documented in the `MemorySegment` API? What are all the > bad things that can happen? > - Tearing of unaligned access - can it also tear if the user has ensured > alignment? > - Repeated instructions (like the repeated copy I pointed out above). > > It is of course a little surprising that you lose the Java memory model > guarantees of instruction ordering if you wrap an array in a `MemorySegment`. > > > We have discussed the possibility of threads seeing different values, > > > like in the above example by @eme64. We think this is ok because there > > > are no guarantees of inter-thread visibility for memory segments. This > > > has to be provided externally (e.g., using volatile/CAS operations). > > > There are other cases where we are susceptible to similar problems (e.g, > > > when doing unaligned long access). In short, segments do not fulfill all > > > the aspects of the normal Java memory model (like for arrays). > > > > > > Hmm, I see. Is this documented in the `MemorySegment` API? What are all the > > bad things that can happen? > > > > * Tearing of unaligned access - can it also tear if the user has ensured > > alignment? > > * Repeated instructions (like the repeated copy I pointed out above). > > > > It is of course a little surprising that you lose the Java memory model > > guarantees of instruction ordering if you wrap an array in a > > `MemorySegment`. > > This is unavoidable. Consider the case where we have a wrapped `long[]` in a > segment, and then we get a new `var s2 = segment.asSlice(1)` on which we > operate with long semantics... Absolutely, we cannot avoid tearing. At least not for unaligned access. But one might hope that aligned accesses would not tear. I don't know enough about the details here, but it seems to me that repeating instructions is a slightly different category. It does not seem unavoidable. But maybe we are willing to do it too, so we can get out some more performance. I suppose in the end we can do whatever we want, as long as we ensure the user can understand what the guarantees are ;) I quickly scanned the `MemorySegment` documentation, and I could not see anything about memory model or visibility guarantees. As a user, I now would assume that this means that the Java memory model applies. At least as long as I stay away from unaligned accesses. Well, there is a note for `JAVA_DOUBLE_UNALIGNED`, for example: `Care should be taken when using unaligned value layouts as they may induce performance and portability issues.` Why not just mention tearing directly? ------------- PR Comment: https://git.openjdk.org/jdk/pull/26672#issuecomment-3184191184