Análise da saída x86 gerada pelo JIT no contexto de volatilidade

Estou escrevendo este post em conexão comProfundo entendimento de volátil em 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);
    }
}

Agora, estou analisando o que o JIT gerou para o trecho de código acima. De nossa discussão no meu post anterior, sabemos que a saída1, 0 é impossível porque:

escreva para volátilv faz com que toda açãoa precederv faz com quea ficará visível (será liberado na memória) antes dev será visível.

   .................(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

Entendo corretamente que funciona porque o x86 não podeStoreStore reordenar? Se pudesse exigir barreira adicional à memória, sim?

EDITADO APÓS EXCELENTE resposta de Eugene @:

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

Aqui, eu entendo o que você quer dizer - é claro:every action below (after) leitura volátil (int tmp = i) não é reordenado.

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

Aqui, você coloca mais uma barreira. Ele garante que nenhuma ação será reordenada comint tmp = i. Mas, por que isso é importante? Por que eu tenho dúvidas? Pelo que eu seivolatile load garante:

Toda açãodepois de a carga volátil não será reordenada antes que a carga volátil seja visível.

Vejo você escrever:

Precisa haver uma consistência sequencial

Mas não vejo por que a consistência sequencial é necessária.

questionAnswers(1)

yourAnswerToTheQuestion