São barreiras de memória necessário para o atomic contagem de referência compartilhado imutável de dados?

StackOverflow https://stackoverflow.com/questions/2599238

Pergunta

Eu tenho alguns imutável estruturas de dados que eu gostaria de gerenciar usando as contagens de referência, compartilhá-los através de threads em um sistema SMP.

Aqui está o que o código de liberação parece:

void avocado_release(struct avocado *p)
{
    if (atomic_dec(p->refcount) == 0) {
        free(p->pit);
        free(p->juicy_innards);
        free(p);
    }
}

Não atomic_dec precisa de uma barreira de memória ela tem?Se assim for, que tipo de barreira de memória?

Notas adicionais:O aplicativo deve ser executado em PowerPC e x86, de modo que qualquer processador de informações específicas é bem-vinda.Eu já sei sobre o GCC atômica builtins.Como para a imutabilidade, o refcount é o apenas campo alterações ao longo da duração do objeto.

Foi útil?

Solução

Em x86, ele vai se transformar em um bloqueio de prefixo de instrução de montagem, como LOCK XADD.
Sendo uma única instrução, ele não é passível de interrupção.Como um "recurso", o prefixo lock resulta em uma barreira de memória completa:

"...bloqueado operações de serializar em circulação, carga e operações de armazenamento (que é, esperar por eles para completar)." ..."Bloqueado operações são atômica com relação a todas as outras operações de memória e todos os visível externamente eventos.Apenas a instrução fetch e de tabela de página de acessos pode passar bloqueado instruções.Bloqueado instruções pode ser usado para sincronizar os dados gravados por um processador e lido por outro processador." - Intel® 64 e IA-32 Arquiteturas Manual do Desenvolvedor de Software, Capítulo 8.1.2.

Uma barreira de memória é de fato implementado como um manequim LOCK OR ou LOCK AND em ambos os a .NET e o JAVA JIT no x86/x64.
Para que você tenha uma completa vedação em x86 como um bônus adicionado, quer você goste ou não.:)

No caso do PPC, é diferente.Um LL/SC par - lwarx & stwcx - com uma subtração de dentro pode ser usado para carregar a memória operando em um registro, subtrair um, em seguida, escrevê-lo de volta, se não havia nenhuma outra loja para o local de destino, ou repetir todo o ciclo se houve.Um LL/SC pode ser interrompido.
Ele também não significa uma completa automática cerca.
No entanto, isto não comprometer a atomicidade do contador em qualquer forma.
Significa apenas que a x86 caso, acontecer de você receber uma cerca, bem como, "de graça".
No PPC, pode-se inserir uma completa vedação através da emissão de um (lw)sync instrução.

Tudo em tudo, explícita barreiras de memória não são necessários para o atomic contador para funcionar corretamente.

Outras dicas

É importante distinguir entre atômica de acessos (que garantem que a ler/modificar/escrever o valor executado como uma unidade atômica) e reordenação de memória.

Memória barreiras impedem a reordenação de leituras e gravações e o reordenamento é completamente ortogonais para a atomicidade.Por exemplo, em PowerPC se você implementar o mais eficiente incremento atômico possível, então, isso não vai impedir que reordenação.Se você deseja impedir que reordenação, em seguida, você precisa de um lwsync de sincronização ou de instrução, ou algum equivalente de alto nível (C++ 11?) barreira de memória.

Afirma que "não há possibilidade de o compilador reordenação as coisas de uma problemática de forma" parecer ingénuo, como afirmações gerais devido a otimizações de compilador pode ser bastante surpreendente e porque CPUs (PowerPC/BRAÇO/Alfa/MIPS em particular) de forma agressiva reordenar as operações de memória.

Coerente cache não salvar você.Ver http://preshing.com/ para ver como a memória reordenação realmente funciona.

Neste caso, no entanto, creio que a resposta é que não há barreiras são necessários.Isso porque, para este caso específico (contagem de referência) não há necessidade de uma relação entre a contagem de referência e os outros valores no objeto.A única exceção é quando a contagem de referência atinge zero.Nesse ponto, é importante garantir que todas as atualizações de outros segmentos são visíveis para a thread atual para uma leitura adquirir barreira pode ser necessário.

Você está com a intenção de implementar o seu próprio atomic_dec ou você está apenas querendo saber se um sistema fornecido função irá se comportar como pretende?

Como regra geral, fornecido pelo sistema atômico de incremento/decremento instalações serão aplicáveis seja qual for barreiras de memória são necessários para fazer a coisa certa.Geralmente você não precisa se preocupar com barreiras de memória, a menos que você está fazendo algo maluco como implementar o seu próprio cadeado, livre de estruturas de dados ou um STM biblioteca.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top