Barreiras interligadas e de memória

Eu tenho uma pergunta sobre o exemplo de código a seguir (m_value não é volátil e cada thread é executado em um processador separado)

void Foo() // executed by thread #1, BEFORE Bar() is executed
{
   Interlocked.Exchange(ref m_value, 1);
}

bool Bar() // executed by thread #2, AFTER Foo() is executed
{
   return m_value == 1;
}

Faz usandoInterlocked.Exchange em Foo () garante que quando Bar () for executado, eu verei o valor "1"? (mesmo que o valor já exista em um registro ou linha de cache?) Ou eu preciso colocar uma barreira de memória antes de ler o valor dem_value?

Também (sem relação com a questão original), é legal declarar um membro volátil e passá-lo por referência aInterlockedXX métodos? (o compilador avisa sobre a passagem de voláteis por referência, então devo ignorar o aviso nesse caso?)

ObserveEu não estou procurando por "melhores maneiras de fazer as coisas", então por favor não poste respostas que sugiram maneiras completamente alternativas de fazer coisas ("use um bloqueio ao invés" etc.), essa questão vem de puro interesse.

questionAnswers(7)

yourAnswerToTheQuestion