title: Should volatile be used when mapping GPU memory?
body: <p>Both OpenGL and Vulkan allow to obtain a pointer to a part of GPUs memory by using <code>glMapBuffer</code> and <code>vkMapMemory</code> respectively. They both give a <code>void*</code> 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 <code>float*</code> to interpret the memory as an array of floats or vectors or similar.</p>
  <p>It seems that any kind of memory mapping <a href="https://stackoverflow.com/questions/53340727/how-to-properly-access-mapped-memory-without-undefined-behavior-in-c">is undefined behaviour</a> 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 <code>volatile</code>.</p>
  <p>In the linked question the pointer is additionally marked as <code>volatile</code> 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 <code>volatile</code> in this context (more broadly, this keyword seems to be barely used at all nowadays).</p>
  <p>At the same time in <a href="https://stackoverflow.com/questions/45753903/memory-mapped-files-and-pointers-to-volatile-objects">this question</a> the answer seems to be that using <code>volatile</code> is unnecessary. This is due to the fact that the memory they speak of is mapped using <code>mmap</code> and later given to <code>msync</code> 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.</p>
  <p>In case of the memory being mapped as not <code>GL_MAP_FLUSH_EXPLICIT_BIT</code> or it being <code>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</code> than no flushing is needed at all and the memory contents update automagically. Even if the memory is flushed by hand by using <code>vkFlushMappedMemoryRanges</code> or <code>glFlushMappedBufferRange</code> 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.</p>
  <p>As such, <strong>is it necessary to mark pointers to mapped GPU memory as <code>volatile</code></strong>? I know that technically this is all undefined behaviour, but I am asking what is required in practice on real hardware.</p>
  <p>By the way, neither the <a href="https://www.khronos.org/registry/vulkan/specs/1.2/pdf/vkspec.pdf" rel="nofollow noreferrer">Vulkan Specification</a> or the <a href="https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf" rel="nofollow noreferrer">OpenGL Specification</a> mention the <code>volatile</code> qualifier at all.</p>
  <p>EDIT: Would marking the memory as <code>volatile</code> incur a performance overhead?</p>