Does implicit synchronization take effects when writing persistent mapped buffers?

I have read the OpenGL wiki on Implicit Synchronization: Synchronization - OpenGL Wiki, but I don’t quite comprehend it, so I post this thread here to double check my understanding.

What I want to know is when implicit synchronization takes effects when I use coherent persistent mapping for buffer update. Suppose the OpenGL (seudo-)code is as follows

glBufferStorage(GL_ARRAY_BUFFER, bufferSize, 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
pBufferData = glMapBufferRange(GL_ARRAY_BUFFER, 0, bufferSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
for(;;) {
  //Generate new data and save them into pBufferData on CPU side
  pBufferData[i++]=....;
  glDrawArrays(GL_TRIANGLES, 0, triangleCount * 3);
}

According to the wiki, “Most attempts to write to a buffer object, either with glBufferSubData or mapping, will halt until all rendering commands using that part of the buffer object have completed.” Here I am using mapping to write buffer object, so the implicit synchronization should take effects so that I don’t need to worry about racing, right? That is, the assignment statement pBufferData[i++]=…; should halt. But so far as I know, the subject of implicit synchronization should be an OpenGL operation, i.e., an OpenGL API. Will simply assigning values to the mapped pointer cause implicit synchronization? I think not, for, how could OpenGL know that? If not, what does the above quoted sentence in the wiki mean? How does persistent mapping cause implicit synchronization? Furthermore, the wiki also says “If you use the GL_MAP_UNSYNCHRONIZED_BIT flag with glMapBufferRange, OpenGL will forgo any synchronization operations;” That means if I do not use GL_MAP_UNSYNCHRONIZED_BIT in glMapBufferRange, as I did in the above code, implicit synchronization should be in effect, right? So whether on earth does implicit synchronization take effects in the above code? Thank you.

Here I am using mapping to write buffer object

No, you’re using persistent mapping. With non-persistent mapping, a buffer that is mapped cannot be used period. With persistent mapping, you can use a mapped buffer, but you take it upon yourself to synchronize any user/GPU accesses to it.

That means if I do not use GL_MAP_UNSYNCHRONIZED_BIT in glMapBufferRange, as I did in the above code, implicit synchronization should be in effect, right?

MAP_UNSYNCHRONIZED refers to the synchronization of the glMapBufferRange call.

Can you detail your reply? I have no idea what you were talking about.

I don’t understand what you don’t understand from my reply. Do you not understand what persistent mapping is? Do you not understand what unsychronized mapping is? What is the part that has you confused?

I don’t understand your reply because, I asked “what time is it?”, you answered “the milk is white”, and continue to ask “Do you not understand what milk is?” and “Do you not understand what white color is?”.

I understand what persistent mapping is, because I have cited the OpenGL wiki which I have of course read. But I am not asking “what persistent mapping is”. I don’t understand why you give me that reply.

Likewise, I am not asking what unsychronized mapping is.

I don’t understand why you senior guys always like assuming what is asked instead of understanding what is asked.

I don’t agree with your characterization of this conversation. I’d say it’s more like:

You: I have some white milk. Should it be warm?

Me: Milk is kept fresh by being cold.

You: But I was asking about it being warm.

Me: … don’t you like fresh milk?

Because you gave an example of persistent mapping and asked how it behaves. So how can I do anything but answer with a discussion of persistent mapping? You gave the example; if you didn’t want it to be about persistent mapping, you should not have included it.

The thing you don’t seem to be understanding is what “implicit synchronization” means, which is why I explained how non-persistent mapping works.

When you map a buffer, OpenGL will halt until all GPU accesses to the mapped buffer range have completed; this is “implicit sychronization”. Implicit synchronization applies to the mapping call; nothing else.

Coupled with this is the fact that non-persistent mapping means that the GPU cannot access the buffer while it is mapped. Therefore, if you map a buffer, all changes to it are effectively atomic. You can change what you like while it is mapped. But you can’t use it for anything until you unmap it.

Note that this latter fact is not “implicit synchronization”. There’s no need for synchronization after the mapping because the GPU flat out cannot access it anymore until it is unmapped.

Persistent mapping changes that latter rule; the GPU can access a mapped buffer range while it is mapped. Because of that, you are now required to do synchronization yourself. You cannot modify mapped memory the GPU is currently reading from, and you cannot have the GPU write to memory that you’re currently reading from.

That doesn’t (necessarily) change anything about the glMapBufferRange call. It may still have “implicit synchronization”. But it doesn’t matter, because you still have to do explicit synchronization when modifying the actual memory in the buffer.

But again, you brought it up. “if I do not use GL_MAP_UNSYNCHRONIZED_BIT in glMapBufferRange, as I did in the above code, implicit synchronization should be in effect, right?”. That’s asking about how the unsynchronized bit (or the absence thereof) affects synchronization.