Cercas de memória - Precisa de ajuda para entender

Estou lendo Barreiras à Memória, de Paul E. McKenneyhttp://www.rdrop.com/users/paulmck/scalability/paper/whymb.2010.07.23a.pdf tudo é explicado em grandes detalhes e, quando vejo que tudo está claro, encontro uma frase, que oculta tudo e me faz pensar que não entendi nada. Deixe-me mostrar o exemplo

void foo(void)
{
   a = 1; #1
   b = 1; #2
}

void bar(void)
{
   while (b == 0) continue; #3
   assert(a == 1); #4
}

digamos que essas duas funções estejam sendo executadas em processadores diferentes. Agora, o que poderia acontecer é que o armazenamento em um número 1 pudesse ser visto após o armazenamento em número 2 no segundo processador, porque as filas do primeiro processador armazenam em "a" e continuam a armazenar as instruções b. OK, tudo bem, nós adicionamos uma cerca de gravação na linha entre # 1 e # 2, mas esse código ainda pode falhar, porque o segundo processador pode enfileirar a mensagem inválida, então adicionamos mais uma cerca de memória (leia cerca desta vez) em a linha entre # 4 e # 4.

void foo(void)
{
   a = 1; #1
   write_memory_barrier();
   b = 1; #2
}

void bar(void)
{
   while (b == 0) continue; #3
   read_memory_barrier();
   assert(a == 1); #4
}

isso impõe o segundo processador para processar todas as mensagens na fila (invalide a) e leia-o novamente enviando mensagem MESI de leitura para o primeiro processador no 4. ESTÁ BEM. Em seguida, o artigo diz

Muitas arquiteturas de CPU, portanto, fornecem instruções mais fracas de barreira à memória que fazem apenas uma ou a outra dessas duas. Grosso modo, uma “barreira de memória de leitura” marca apenas a fila inválida e uma “barreira de memória de gravação” marca apenas o buffer de armazenamento. enquanto uma barreira de memória completa faz as duas coisas.

Ótimo, está claro, mas depois disso eu vejo isso

O efeito disso é que uma barreira de memória de leitura solicita apenas carregamentos na CPU que a executa, para que todas as cargas anteriores à barreira de memória de leitura pareçam ter sido concluídas antes de qualquer carregamento após a barreira da memória de leitura. Da mesma forma, uma barreira de memória de gravação solicita apenas armazenamentos, novamente na CPU que a executa, e novamente para que todos os armazenamentos que precedem a barreira de memória de gravação pareçam ter sido concluídos antes de qualquer armazenamento após a barreira de memória de gravação.

tão

todas as cargas anteriores à barreira da memória de leitura parecerão ter sido concluídas antes de qualquer carga após a barreira da memória de leitura

que mistura tudo o que foi explicado antes. O que isso significa? Qual carga na função "bar" deve ser concluída antes do carregamento de "a" # 4? Entendo que a declaração pode falhar sem barreira de memória nessa função, apenas porque o processador pode ler um valor antigo, porque ainda não conseguiu invalidar sua linha de cache, onde o objeto "a" está localizado.

Explicação em detalhes seria realmente útil, estou tentando entender o dia todo.

Muito obrigado antecipadamente.

questionAnswers(1)

yourAnswerToTheQuestion