1. Memória Compartilhada e Distribuída
_ Notas de Aula _
Prof. Tiago Garcia de Senna Carneiro
DECOM/UFOP
• Introdução
Um sistema de memória compartilhada faz a memória física global de um sistema
igualmente acessível por todos os processadores. Apesar de permitir fácil programação, os
sistemas deste tipo sofrem problemas de contenção e de alta latência para fazer acesso à
memória compartilhada, o que degrada a performance e limita a escalabilidade das
aplicações.
Um sistema de memória distribuída consiste em múltiplos nodos de processamento
independentes com módulos de memória privativos, conectados por uma rede de
comunicação. A escalabilidade natural destes sistemas permitem o desenvolvimento de
aplicações com um poder de computação muito alto. O projeto de softwares para este
sistemas são mais complexos, porém o projeto de hardware é mais fácil que num sistema
de memória compartilhada.
Visando aproveitar as vantagens destes dois sistemas surgiram os sistemas de memória
compartilhada distribuída. Um sistema de memória compartilhada distribuída que, a
partir de agora, chamaremos DSM - Distributed Shared Memory, implementa logicamente
um sistema de memória compartilhada sobre um sistema de memória distribuída. O DSM
torna transparente ao programador o mecanismo de comunicação remota, preservando a
fácil programação e portabilidade típica de um sistema de memória compartilhada. Além de
apresentar uma boa escalabilidade.
• Estrutura e Organização de um Sistema DSM
2. Três questões principais estão envolvidas no acesso a dados internos ao espaço de
endereçamento de um DSM, quando desejamos garantir a consistência desses dados:
1. Como o será realizado o acesso? - o algoritmo DSM.
2. Onde o acesso é implementado ?- nível da implementação do mecanismo de DSM.
3. Qual o significado preciso da palavra consistência? - modelo de consistência de
memória.
• Algoritmo DSM
O algoritmo para implementação da DSM lida com dois problemas básicos:
• distribuição estática e dinâmica dos dados compartilhados através do sistema,
visando minizar a latência, e
• preservar uma visão coerente dos dados compartilhados, minimizando a sobrecarga
imposta pelo gerenciamento desta coerência
Duas estratégias frequentemente utilizadas para distribuir os dados compartilhados são
replicação e migração. Replicação permite que múltiplas cópias de um mesmo dado resida
em diferentes memórias locais. É utilizado principalmente para permitir acessos
simultâneos por diferentes processadores ao mesmo dado, quando predominam ‘leituras’ na
me memória compartilhada.. Migração implica que somente uma cópia de um dado existe
em um dado momento, então o dado deve ser movido quando um processador o requer para
acesso exclusivo. Esta estratégia diminui a sobrecarga de gerenciamento de coerência,
portanto é utilizada quando predominam ‘escritas’ na memória compartilhada.
Algoritmos DSM foram classificados por Michael Stumn e Songnian Zhou nas seguintes
categorias:
1. leitura simples/ escrita simples: esta classe de algoritmos proíbe replicação,
enquanto permite mas não requer migração. O algoritmo DSM mais simples é um
servidor central. Esta aproximação sofre de problemas de conteção uma vez que o
nodo central pode se tornar um gargalo no sistema. Algoritmos SRSW mais
avançados permitem migração. Entretanto somente uma cópia do dado existe em um
3. dado momento, e esta cópia pode migrar sob demanda. Este tipo de algoritmo é
chamado bot potato. Se uma aplicação apresenta localidade referencial alta, o custo
da migração dos dados é amortizado sobre vários acessos, porque os dados são
movidos não como itens individuais, mas como unidades (blocos) de tamanho fixo.
De qualquer maneira, a performance deste algoritmo raramente usado é muito baixa.
Pois não é explorada a possibilidade de leituras em paralelo.
2. leitura múltipla/ escrita simples: estes algoritmos permitem a execução local de
operações de leituras em vários processadores. Somente um processador possui
permissão para atualizar uma cópia replicada em um dado momento. Portanto,
algoritmos MRSW são comumente baseados em invalidação, isto é, após um
processador escrever sobre um bloco de dados compartilhado ele deve invalidar
todas as outras cópias desse bloco. Algoritmos desta classe diferem na alocação da
responsabilidade de gerenciar a DSM:
- gerente: existe um único processador responsável por organizar acessos de escrita
à memória compartilhada,
- proprietário: o processador que possui a única cópia atualizável do bloco de
dados,
- conjunto cópia: conjunto de processadores que possuem uma cópia do bloco de
dados para leitura
3. múltipla/ escrita múltipla: algoritmos MRMW permitem replicação de blocos de
dados com permissão tanto para leitura quanto para escrita. Para preservar a
coerência, todas as cópias em processadores remotos devem ser atualizadas, por
broadcasting ou multicasting, quando uma cópia é atualizada . Como este algoritmo
tenta minimizar o custo de acessos de escrita, é apropriado para escrita
compartilhada. Este algoritmo pode apresentar um alto tráfego de coerência,
especialmente quando a frequência de atualização e o número de cópias replicadas
são altas.
• Nível de Implementação dos Mecanismos DSM
Como o espaço de endereçamento da DSM é distribuído em memórias locais, uma pesquisa
numa tabela deve ser executada em cada acesso à dados compartilhados para determinar se
o dado requerido está na memória local. Se não estiver, o sistema deve trazer o dado para a
memória local. O sistema também deve tomar uma ação em um acesso de escrita para
preservar a coerência dos dados compartilhados. Tanto a ação quanto a pesquisa na tabela
podem ser realizadas por software, por hardware, ou por uma combinação destes (híbrido).
A escolha da implentação geralmente depende da relação custo/benefício.
DSM por software pode ser implementada em nível de usuário, como uma biblioteca de
rotinas run-time, como parte do SO, ou como uma liguagem de programação.
• Modelos de Consistência de Memória
O modelo de consistência de memória define a ordem forma legal de um processador fazer
acessos à memória compartilhada, quando observado por outro processador.
Formas fortes de modelos de consistência tipicamente aumentam a latência de acesso à
4. memória e a bandwith requerida, enquanto facilitam a programação. Modelos mais
relaxados, os quais permitem reordenação, pipelining, e sobreposição, consequentemente
melhoram a performance, mas exigem um alto envolvimento do programador na
sincronização de acesso à dados compartilhados. Para otimizar este comportamento,
sistemas com múltiplos modelos de consistência têm surgido.
Modelos de memória fortes que tratam acessos de sincronização da mesma forma que
operações de escrita e leitura são chamados consistência sequencial e processador.
Modelos mais relaxados que distinguem entre acessos de sincronização e acessos de leitura
e escrita são chamados consistência weak, release, lazy release, e entry.
Consistência sequencial pode ser conseguida forçando acessos serializados à memória
compartilhada por meio de uma fila FIFO.
Consistência processador assume que a ordem na qual diferentes processadores podem ver
operações de memória não precisam ser identicas, mas todos os processadores devem
observar a sequencia de writes demandada por cada processador na mesma ordem.
Diferente da consistência sequencial, a consistência processador permite que operações de
leitura passem a frente de operações de escrita na fila a partir da qual requisições de
memória são servidas.
Consistência weak requer que a memória se torne consistente somente em acessos de
sincronização. Um acesso de sincronização deve esperar por até que todos os acessos
anteriores sejam completados, enquanto operações de leitura e escrita devem esperar
somente que acessos de sincronização anteriores sejam completados.
Consistência release divide acesso de sincronização em acessos acquire e release, de forma
a proteger acessos à memória compartilhada entre o par acquire-release. Neste modelo
acessos de escrita e leitura podem executar somente após todos os prévios acquires no
mesmo processador tenham completado. Além disso, acessos release podem executar
somente após todos as prévias operações de leitura e escrita tenham completado.
Consistência lazy release é um melhoramento da consistência release. Invés de propagar as
modificações na memória compartilhada em cada release, as modificações esperam até que
um próximo acquire relevante. Isto minimiza a quantidade de dados trocados pelos
processadores.
• Aspectos de Projeto
Configuração do cluster: como cada processador possui sua cache local, a coerência de
cache a nível de cluster deve ser integrada globalmente com o mecanismo DSM. Partes do
modulo de memória local podem ser configurados como privado ou compartilhado.
Redes de interconexão: a topologia da rede de interconexão pode melhorar ou restringir o
potencial para troca paralela de informação relacionada ao gerenciamento da DSM.
Também determina o custo de transações de broadcast e multicast.
Estrutura dos dados compartilhados: a estrutura dos dados compartilhados representam o
5. layout global do espaço de endereçamento compartilhado, bem como a organização dos
itens de dados. Soluções por hardware sempre lidam com objetos de dados não
estruturados, enquanto implementações por softwares tendem a utilizar itens de dados que
representam entidades lógicas, para tirar vantagem da localidade naturalmente expressa
pelas aplicações.
Granularidade da unidade de coerência: esta granularidade determina o tamanho dos blocos
de dados gerenciados pelos protocolos de coerência. Tipicamente, sistemas orientados a
hardware usam unidades menores (blocos de cache), enquanto soluções por software,
baseadas em mecanismos de memória virtual, organizam dados em blocos de memória
maiores (páginas). Em um fenômeno chamado false sharing, o uso de blocos maiores
salvam espaço para armazenamento de diretórios, mas também aumentama probabilidade
de múltiplos processadores solicitarem acessos a um mesmo bloco simultaneamente,
mesmo se eles estiverem fazendo acesso à partes não relacionadas do bloco. Isto pode
causar disperdício.