Análisis de la salida x86 generada por JIT en el contexto de volátiles

Estoy escribiendo esta publicación en relación conProfundo conocimiento de volátiles en Java

public class Main {
    private int x;
    private volatile int g;


    public void actor1(){
       x = 1;
       g = 1;
    }


    public void actor2(){
       put_on_screen_without_sync(g);
       put_on_screen_without_sync(x);
    }
}

Ahora, estoy analizando lo que JIT generó para el fragmento de código anterior. De nuestra discusión en mi publicación anterior sabemos que la salida1, 0 es imposible porque:

escribir a volátilv hace que cada accióna precedentev hace quea será visible (se enjuagará en la memoria) antesv será visible

   .................(I removed not important body of method).....

  0x00007f42307d9d5e: c7460c01000000     (1) mov       dword ptr [rsi+0ch],1h
                                                ;*putfield x
                                                ; - package.Main::actor1@2 (line 14)

  0x00007f42307d9d65: bf01000000          (2) mov       edi,1h
  0x00007f42307d9d6a: 897e10              (3) mov       dword ptr [rsi+10h],edi
  0x00007f42307d9d6d: f083042400          (4) lock add  dword ptr [rsp],0h
                                                ;*putfield g
                                                ; - package.Main::actor1@7 (line 15)

  0x00007f42307d9d72: 4883c430            add       rsp,30h
  0x00007f42307d9d76: 5d                  pop       rbp
  0x00007f42307d9d77: 850583535116        test      dword ptr [7f4246cef100h],eax
                                                ;   {poll_return}
  0x00007f42307d9d7d: c3                  ret

¿Entiendo correctamente que funciona porque x86 no puede hacerStoreStore reordenamiento? Si pudiera, requeriría una barrera de memoria adicional, ¿sí?

EDITADO DESPUÉS DE LA EXCELENTE respuesta de @ Eugene:

 int tmp = i; // volatile load
 // [LoadStore]
 // [LoadLoad]

Aquí, veo a qué te refieres: está claro:every action below (after) lectura volátilint tmp = i) no se reordena.

 // [StoreLoad] -- this one
 int tmp = i; // volatile load
 // [LoadStore]
 // [LoadLoad]

Aquí, pones una barrera más. Nos asegura que no se reordenará ninguna acción conint tmp = i. Pero, ¿por qué es importante? ¿Por qué tengo dudas? Por lo que sévolatile load garantías:

Cada accióndespués la carga volátil no se reordenará antes de que la carga volátil sea visible.

Te veo escribir:

Debe haber una coherencia secuencial

Pero, no puedo ver por qué se requiere coherencia secuencial.

Respuestas a la pregunta(1)

Su respuesta a la pregunta