Both OpenGL and Vulkan allow to obtain a pointer to a part of GPUs memory by using glMapBuffer
and vkMapMemory
respectively. They both give a void*
to the mapped memory. To interpret its contents as some data it has to be cast to an appropriate type. The simplest example could be to cast to a float*
to interpret the memory as an array of floats or vectors or similar.
It seems that any kind of memory mapping is undefined behaviour in C++, as it has no notion of memory mapping. However, this isn't really an issue because this topic is outside of the scope of the C++ Standard. However, there is still the question of volatile
.
In the linked question the pointer is additionally marked as volatile
because the contents of the memory it points at can be modified in a way that the compiler cannot anticipate during compilation. This seems reasonable though I rarely see people use volatile
in this context (more broadly, this keyword seems to be barely used at all nowadays).
At the same time in this question the answer seems to be that using volatile
is unnecessary. This is due to the fact that the memory they speak of is mapped using mmap
and later given to msync
which can be treated as modifying the memory, which is similar to explicitly flushing it in Vulkan or OpenGL. I'm afraid though that this doesn't apply to neither OpenGL nor Vulkan.
In case of the memory being mapped as not GL_MAP_FLUSH_EXPLICIT_BIT
or it being VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
than no flushing is needed at all and the memory contents update automagically. Even if the memory is flushed by hand by using vkFlushMappedMemoryRanges
or glFlushMappedBufferRange
neither of these functions actually takes the mapped pointer as a parameter, so the compiler couldn't possibly know that they modify the mapped memory's contents.
As such, is it necessary to mark pointers to mapped GPU memory as volatile
? I know that technically this is all undefined behaviour, but I am asking what is required in practice on real hardware.
By the way, neither the Vulkan Specification or the OpenGL Specification mention the volatile
qualifier at all.
EDIT: Would marking the memory as volatile
incur a performance overhead?
vkMapMemory
mentionvolatile
in the type? – Paganismvolatile
provides any guarantees, then it is literally completely useless to you. What you need is a guarantee of proper operation. If the platform doesn't give you one withvolatile
, then it's of no help at all. You are giving up compiler optimizations for nothing. If the compiler supports OpenGL and/or Vulkan, then it won't make optimizations that causes code that complies with those standards to do the wrong thing anyway. And if they're unsupported, you're in "gee, I hope it works" territory either way and should get out of that territory somehow. – Monodicvolatile
a clever (optimizing) compiler could decide that the region of memory being addressed could not (had not) been updated by the program and remove all the reads of it. Writes could also be optimized away if the compiler can prove program does not read the region of memory. – Cestus