Como um barramento de memória compartilhada é usado para leituras e gravações de dados compartilhados entre threads de maneira segura e correta?


1

Gostaria de entender em alto nível como o barramento de memória compartilhada lida com várias leituras e gravações simultâneas de dados compartilhados de vários segmentos em execução em vários processadores?

PS: Eu não preciso dos detalhes, pois obviamente será específico da implementação. Eu só preciso de uma visão geral de alto nível do que acontece nos bastidores.


1
Você está preso em algum lugar com sua própria pesquisa? Qual é o seu entendimento até agora?
Dave

@DaveRook Tanto quanto eu entendi, o barramento de memória é necessário para se comunicar entre o processador e a RAM (memória principal). É chamado de compartilhado , pois será usado por vários núcleos ao mesmo tempo. A questão é mais especificamente sobre como esse barramento compartilhado é usado sem corromper os dados compartilhados que fluem entre eles. Eu estou procurando uma resposta de alto nível aqui.
Geek

Agora essa é uma pergunta melhor :)! Eu sugiro que você edite sua postagem original com isso, pois você obterá mais respostas.
Dave

@DaveRook atualizou a questão conforme sua sugestão. Espero que agora receba muitas respostas de qualidade.
Geek

Respostas:


1

Um "bus" é um conjunto de fios entre componentes, em vez de um componente em si. Portanto, a fiação entre uma CPU e sua memória é chamada de barramento de memória; a fiação para as placas de expansão é o barramento PCI, etc.

É possível ter vários componentes acionando um barramento, embora apenas um possa acioná-lo de uma só vez, e seus sinais são entregues a todos os outros componentes do barramento. O componente que controla o acesso ao barramento é chamado de mestre de barramento . Pode ser possível alterar qual componente é o mestre do barramento por arbitragem .

Em um sistema multi-core, a consistência do cache é importante. Assim, quando um núcleo grava no barramento de memória compartilhada, outros núcleos irão espionar o barramento (examine a gravação mesmo que ela esteja indo de outro núcleo para a memória). Se a gravação for em um local armazenado em cache por esse núcleo, o núcleo removerá ou substituirá sua entrada de cache. Dessa forma, não tem informações obsoletas.


"É possível ter vários componentes acionando um barramento, embora apenas um possa acioná-lo de uma só vez e seus sinais sejam entregues a todos os outros componentes do barramento". Quais são os múltiplos componentes que direcionam o barramento de memória ?
Geek

@Geek Nos chipsets de PC, não acho que tenhamos mais de um. Ela costumava ser o "northbridge" (controlador de memória / hub), agora é o controlador de memória embutido na CPU. Isso nem sempre foi o caso. Nos minicomputadores clássicos, como o PDP-11 original, a memória ficava apenas na Unibus, junto com os dispositivos de E / S, e os dispositivos de CPU e DMA podiam "dirigi-la". Um protocolo de arbitragem de barramento simples garantiu que apenas um dispositivo pudesse fazê-lo de uma só vez e também era usado para implementar interrupções de prioridades vãs (BR, níveis de "solicitação de barramento").
Jamie Hanrahan

1

Um módulo de memória (um DIMM) só pode fazer uma coisa de cada vez: uma leitura ou uma gravação. Isso é determinado pelo protocolo no conector de borda do DIMM; uma vez que você envia um comando de leitura ou escrita para um DIMM, ele não pode nem mesmo "ouvir" outro até que o comando anterior esteja completo.

Todos os DIMMs em um barramento de memória comum terão coletivamente essa restrição um por vez. Mas em muitas plataformas de PC existem dois ou três canais de memória , e toda a RAM em um canal pode coletivamente fazer apenas uma coisa de cada vez.

Em máquinas NUMA (aquelas com múltiplos soquetes de CPU e memória "privada" para cada soquete) tudo isso é multiplicado por nCPUs. ou seja, cada CPU pode acessar sua memória local, independentemente do que a outra CPU esteja fazendo com sua memória. No entanto, todos os processadores ainda podem acessar toda a memória RAM, só demora um pouco mais se eles tiverem que passar por outra CPU.

Fundamentalmente, cabe ao código dos aplicativos implementar quaisquer requisitos de serialização que eles tenham para acesso a dados compartilhados. Isso é feito com a ajuda do sistema operacional, que fornecerá vários objetos e funções de sincronização para os aplicativos usarem. Esses objetos têm nomes como semáforos (nome emprestado do sinal da ferrovia), exclusões mútuas (abreviação de "exclusão mútua"), etc. Dependendo do sistema operacional, eles podem implementar um por vez, n-a-vez, gravação exclusiva versus leitura compartilhada, etc., semântica. Essas funções geralmente envolvem "espera" ou "bloqueio": Um thread tenta, por exemplo, adquirir um mutex que, por design, "protege" um recurso compartilhado. Se o mutex já pertence a algum outro segmento, então o segundo (e _n_th) thread solicitante é bloqueado, ou seja,

Cabe aos aplicativos usar essas técnicas quando necessário; o sistema operacional não tem como exigir que, por exemplo, você tenha que possuir um mutex em particular antes de acessar os dados que você pretendia que o mutex protegesse. Esta é uma área de design de programa que pode ser muito difícil para ambos acertarem e terem alto desempenho.

Subsistemas de nível superior, como bancos de dados, têm essa codificação integrada para os dados que gerenciam e apresentam uma interface para o programador que "fala" em termos de elementos do banco de dados em vez de objetos de sincronização: o programador invocaria funções para bloquear uma linha da tabela ou célula individual ou um conjunto de linhas, ou talvez uma tabela inteira, enquanto executa atualizações. Abaixo do mecanismo do banco de dados, serão utilizadas as instalações do sistema operacional, conforme descrito anteriormente.

Internamente, o sistema operacional geralmente implementa essas funções de sincronização com o auxílio de algum tipo de operação de teste e modificação atômica implementada no subsistema de memória. Por "atômica" quero dizer que, uma vez iniciada, a operação é garantida para ser concluída antes que qualquer outra operação atômica possa começar na memória afetada. Um exemplo comumente usado no Windows é a instrução "interlocked compare-and-exchange". x86 / x64 na verdade fornece uma série de instruções, trabalhando em vários tamanhos de dados.

Existem métodos que permitem acesso serializado seguro a dados compartilhados sem usar tais técnicas, mas eles só funcionam para alguns casos especiais (por exemplo, "apenas um leitor e apenas um gravador") ou para determinados tipos de dados.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.