Como _readWriteBarrier propaga a árvore de chamadas?
-
23-09-2019 - |
Pergunta
Estou olhando para este texto no texto documentação Para o Visual C ++ 's _readwriteBarrier intrínseco:
Nas versões anteriores do compilador Visual C ++, as funções _readWriteBarrier e _WriteBarrier foram aplicadas apenas localmente e não afetaram as funções na árvore de chamadas. No Visual C ++ 2005 e posterior, essas funções são aplicadas até a árvore de chamadas.
Eu entendo o que a barreira faz dentro de uma função, mas a "Up the Call Tree" parece implicar que uma função foo()
chamando uma função bar()
pode saber se bar()
contém uma barreira ou não. O que realmente mudou no VC2005 para ativar isso ... a convenção de chamada/ABI, alguma análise global feita pelo compilador ou o quê?
Solução
Os documentos da Sra. Nunca são ótimos, e este é um bom exemplo disso. Existem 2 partes no _readWriteBarrier:
- dizendo à CPU para fazer uma barreira de memória (ou seja, mfence),
- dizendo ao compilador para não otimizar a barreira.
Suspeito que a parte da árvore de chamadas esteja se referindo ao #2. ou seja:
int x = 0;
void foo()
{
x = 7;
_ReadWriteBarrier();
x = 8;
}
Sem a barreira, x = 7 pode ser completamente removido pelo compilador. Com a barreira, ela fica. Agora, que tal uma função que chamadas foo?
void bar()
{
x = 3; // optimized away?
foo();
x = 4;
}
Eu acho que no passado x = 3 poderia ter sido otimizado (o que pode ser difícil para o compilador dizer se isso é permitido ou não), mas agora manterá corretamente as instruções x = 3.
Eu penso.