Introdução Memória Compartilhada e Distribuída _ Notas de Aula _ Prof. Tiago Garcia de Senna Carneiro DECOM/UFOP 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
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
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 à
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
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.