• Nenhum resultado encontrado

Mecanismos de Sincronização Distribuída para Clusters Implementados em Hardware

N/A
N/A
Protected

Academic year: 2021

Share "Mecanismos de Sincronização Distribuída para Clusters Implementados em Hardware"

Copied!
142
0
0

Texto

(1)

SOTÉRIO FERREIRA DE SOUZA

Mecanismos de Sincronização Distribuída

para Clusters Implementados em Hardware

Vitória

2005

(2)
(3)

Dados Internacionais de Catalogação-na-publicação (CIP) (Biblioteca Central da Universidade Federal do Espírito Santo, ES, Brasil)

Souza, Sotério Ferreira de, 1959-

S729m Mecanismos de sincronização distribuída para clusters

implementados em hardware / Sotério Ferreira de Souza. – 2005. 140 f. : il.

Orientador: Alberto Ferreira de Souza. Co-Orientador: Neyval Costa Reis Jr.

Dissertação (mestrado) – Universidade Federal do Espírito Santo, Centro Tecnológico.

1. Sincronização. 2. Computação de alto desempenho. I. Souza, Alberto Ferreira de. II. Reis Jr, Neyval Costa. III. Universidade Federal do Espírito Santo. Centro Tecnológico. IV. Título.

(4)
(5)

Gostaria de agradecer a diversas pessoas que contribuíram, direta ou indiretamente, para a realização deste trabalho.

A minha família pelo amor, apoio e compreensão, sem os quais a caminhada seria muito mais árdua.

Aos amigos Andréa e Peloso, pelo incentivo e suporte até o último instante.

Aos colegas do LCAD: Hallysson, Dijalma, Stiven, Felipe, Fernando, João Paulo, Sérgio e Leonardo, pelo companheirismo e apoio constantes.

Ao Laboratório de Computação Paralela da COPPE/UFRJ pela cessão, por empréstimo, das placas de desenvolvimento VCC - H.O.T. II e pelas importantes discussões técnicas com vários de seus membros, fundamentais para o desenvolvimento deste trabalho.

Ao orientador, professor Alberto Ferreira de Souza, pela dedicação e paciência demonstradas durante todo o Mestrado e, em especial, pela oportunidade que me concedeu. Obrigado!

(6)

“Aprender é a única coisa de que a mente nunca se cansa, nunca tem medo e nunca se arrepende”

(7)

A grande demanda por computação de alto-desempenho gerada por classes importantes de aplicações e os avanços obtidos no desempenho de redes de interconexão e microprocessadores, têm incentivado a pesquisa sobre a utilização de agrupamentos de microcomputadores ligados em rede como plataforma para computação paralela de alto-desempenho. Um dos modelos arquiteturais utilizados em computação paralela é o de memória compartilhada, que é adequado para muitas aplicações, desde que mecanismos eficientes de sincronização do acesso à memória compartilhada estejam presentes na máquina paralela.

O modelo arquitetural de memória compartilhada pode ser implementado em software,

hardware ou em uma combinação dos dois. No caso de agrupamentos de computadores

ligados em rede ou clusters, a memória física está distribuída, mas a infra-estrutura disponível para implementação do sistema de memória virtual mais software de sincronização podem ser utilizados para implementar, por software, sistemas que dão ao programador a abstração de uma arquitetura com memória compartilhada em uma máquina com memória distribuída (Software Distributed Shared Memory – S-DSMs). No entanto, a sobrecarga da rede de comunicação de dados gerada pela emulação de uma memória global compartilhada em um

hardware onde a memória está de fato distribuída limita o desempenho destes sistemas. Esta

deficiência nos motivou a desenvolver este trabalho, no qual implementamos, em hardware programável (em Field-Programmable Gate Array - FPGA), algumas primitivas de sincronização necessárias para a implantação de S-DSM. Este hardware, na forma de placas de desenvolvimento FPGA e cabos de interconexão, implementa uma rede auxiliar que funciona em paralelo com a rede de comunicação de dados. Esta rede auxiliar permite realizar importantes tarefas de sincronização necessárias à implementação de S-DSM, liberando a rede de dados da necessidade do apoio a elas.

Para avaliar nosso sistema de sincronização implementado em hardware realizamos experimentos comparando o tempo de execução das tarefas de sincronização necessárias à S-DSM com e sem nosso hardware de sincronização. Os resultados mostraram que nosso sistema de sincronização realiza estas tarefas de sincronização mais de 40 vezes mais rápido do que por software utilizando a rede de comunicação de dados.

(8)

number of application classes and the technological advances on interconnection networks and microprocessors have fueled the research on clusters of workstations as a parallel computing platform. Shared memory is a parallel computing architectural model well suited for a number of applications, provided that efficient memory access synchronization mechanisms are implemented.

Shared memory parallel architectures can be implemented by using hardware, software or a combination of both. When the parallel machines are network of workstations, also known as clusters, the physical memory is distributed and software based synchronization mechanisms together with the virtual memory infrastructure can be used to implement Software Distributed Shared Memory (S-DSMs), which provide the programmer with a shared memory architecture abstraction on a distributed memory machine. However, the communication network overload, generated by the emulation of a shared memory over a physically distributed memory, limits the performance of these systems. This problem was the motivation of our research work, in which we developed a set of S-DSM synchronization primitives using Field-Programmable Gate Array – FPGAs. This new hardware, that we have designed and implemented with FPGA development boards and interconnection cables, implements an auxiliary synchronization network, which works in parallel with the main data network.

To assess the improvement provided by our synchronization hardware on the performance of synchronization primitives necessary for S-DSM systems, we conducted experiments comparing the execution time of these primitives when implemented in software and in our hardware. Benchmarking parallel programs using an S-DSM system with and without our synchronization hardware. The results showed that our synchronization system increases the performance of these S-DSM primitives on more than 40 times.

(9)

Figura 1.1: Relógio Global implementado em hardware. ... 15

Figura 1.2: Ilustração de um cluster com a rede auxiliar de sincronização. ... 16

Figura 2.1: Estrutura básica de um multiprocessador com memória centralizada compartilhada - adaptada de [Patterson03, p.531]... 21

Figura 2.2: Estrutura básica de um multiprocessador com memória distribuída - adaptada de [Patterson03, p.532]. ... 22

Figura 2.3: Estrutura básica de um cluster - adaptada de [Patterson03, p.532]. ... 23

Figura 2.4: Estados e transições de um processo - adaptada de [Tanenbaum00, p.49]. ... 25

Figura 2.5: Solução de Peterson para obter exclusão mútua - adaptada de [Tanenbaum00, p.56]. ... 28

Figura 3.1: Formato geral das mensagens. ... 33

Figura 3.2: Topologia da Rede Auxiliar de Sincronização. Cada Sincronizador possui uma porta up (para cima) e oito portas down (para baixo). A rede mínima possui dois Nós e um Sincronizador e, na implementação corrente, a rede máxima possui 4 níveis (como acima), com um Sincronizador de Topo, 8 sincronizadores no nível 2 e 64 no nível 3 (73 Sincronizadores); os Sincronizadores são independentes mas, correntemente, são alimentados através de slots PCI de máquinas quaisquer. Cada Nó é conectado a um slot PCI de cada um dos computadores que compõem o cluster servido pela rede. Correntemente, o número máximo de Nós é igual a 512. ... 35

Figura 3.3: Diagrama de tempo de setup e hold. ... 37

Figura 3.4: Diagrama de blocos do Sincronizador de Topo... 39

Figura 3.5: Estrutura de dados das barreiras do Sincronizador de Topo... 43

Figura 3.6: Estrutura de dados dos locks no Sincronizador de Topo... 44

Figura 3.7: Diagrama de blocos do Sincronizador Intermediário... 45

Figura 3.8: Diagrama de blocos do Nó... 50

Figura 3.9: Esquema de sinalização núcleo de controle - transmissor up... 53

(10)

Figura 4.1: Diagrama do ambiente experimental. ... 61

Figura 4.2: Placa H.O.T. II + Mezanino ... 63

Figura 4.3: Trecho do código com barreira por software... 65

Figura 4.4: Trecho de código com barreira por hardware... 66

Figura 4.5: Trecho de código com lock por hardware... 68

Figura 5.1: Comparação entre os tempos médios de execução de barreiras implementadas por hardware e por software em função do número de barreiras implementadas. ... 72

Figura 5.2: Speedup no tempo total de execução do programa de teste em função do número de barreiras implementadas. ... 73

(11)

Tabela 5.2: Implementação de barreiras por software. ... 72 Tabela 5.3: Implementação de lock por hardware. ... 74

(12)

1 INTRODUÇÃO ... 13 1.1 MOTIVAÇÃO ... 17 1.2 OBJETIVOS ... 17 1.3 CONTRIBUIÇÕES... 17 1.4 ORGANIZAÇÃO DA DISSERTAÇÃO ... 18 2 MECANISMOS DE SINCRONIZAÇÃO ... 19 2.1 MÁQUINAS PARALELAS ... 19 2.2 PROCESSOS... 24

2.3 COMUNICAÇÃO ENTRE PROCESSOS ... 25

2.4 SINCRONISMO DE PROCESSOS ... 26 2.4.1 Sleep e Wakeup ... 28 2.4.2 Semáforos ... 28 2.4.3 Monitores ... 29 2.4.4 Passagem de Mensagens ... 30 2.4.5 Barreiras... 30 2.4.6 Locks ... 30 2.4.7 Broadcast ... 31

3 MECANISMOS DE SINCRONIZAÇÃO IMPLEMENTADOS EM HARDWARE .... 32

3.1 OS MECANISMOS DE SINCRONIZAÇÃO ELEITOS ... 32

3.2 ESPECIFICAÇÃO DAS MENSAGENS ... 32

3.3 A TOPOLOGIA DA REDE ... 35

3.4 DESCRIÇÃO DOS DISPOSITIVOS DE HARDWARE ... 38

3.4.1 O Sincronizador de Topo ... 38

3.4.1.1 Gerador de Sinal de Clock ... 39

3.4.1.2 Receptor Down... 40 3.4.1.3 Núcleo de Controle... 40 3.4.1.4 Memória de Barreiras ... 42 3.4.1.5 Memória de Locks ... 43 3.4.1.6 Transmissor Down... 44 3.4.2 O Sincronizador Intermediário ... 44

(13)

3.4.3 O Nó ... 48 3.4.3.1 Relógio Global... 49 3.4.3.2 Receptor Up ... 50 3.4.3.3 Transmissor Up ... 50 3.4.3.4 Núcleo de Controle... 51 3.4.3.5 Metaestabilidade ... 52 3.4.3.6 Memórias do Nó ... 55

3.4.3.7 Interface com o Barramento PCI ... 56

3.4.3.8 Interface com os Cabos de Interconexão ... 57

3.4.4 Os Cabos de Interconexão ... 57

3.4.5 Módulos de Software... 58

4 MÉTODOS... 61

4.1 AMBIENTE EXPERIMENTAL ... 61

4.1.1 Placa de Desenvolvimento FPGA... 61

4.1.2 As Máquinas Hospedeiras ... 63 4.1.3 Programas de Teste ... 64 4.1.4 Métricas ... 69 5 EXPERIMENTOS ... 71 5.1 TEMPO DE BARREIRA ... 71 5.2 TEMPO DE LOCK ... 73 6 DISCUSSÃO ... 75 6.1 TRABALHOS CORRELATOS ... 75

6.2 ANÁLISE CRÍTICA DESTE TRABALHO DE PESQUISA... 77

7 CONCLUSÃO... 80

7.1 SUMÁRIO... 80

7.2 CONCLUSÕES ... 80

7.3 SUGESTÕES DE TRABALHOS FUTUROS ... 81

(14)

ANEXO C – DIAGRAMAS DO SINCRONIZADOR INTERMEDIÁRIO ... 103 ANEXO D – DIAGRAMAS DO SINCRONIZADOR DE TOPO... 125

(15)

(agrupamentos de computadores interligados por uma rede de comunicação) como plataformas para o processamento de alto desempenho. Esses clusters oferecem o que é

genericamente denominado de Cluster-based Network Computing (CNC)

[Dowd95a,Dowd95b]. CNC é uma alternativa atraente e de baixo custo para aplicações que exijam a capacidade computacional equivalente à de supercomputadores a uma fração do seu custo. Dentre as várias classes de importantes aplicações para as quais CNC é atrativa encontram-se a computação de alto desempenho, os sistemas de informações avançados (por exemplo, geológicas e geofísicas para a indústria do petróleo, meteorológicas, médicas, etc.), servidores WWW e aplicações multimídia.

Em clusters, cada processador possui sua própria memória local e um processador não pode acessar a memória de outro diretamente [DeSouza95]. Então, quando esses processadores cooperam para resolver um mesmo problema, dados que estejam na memória de um processador e tenham que ser acessados por outro processador terão que ser transferidos através da rede de comunicação. Esse acesso via rede ocorre em uma velocidade bastante inferior àquela observada quando o dado acessado está na memória local. Esse gargalo pode se tornar um empecilho para que um programa execute mais rapidamente em paralelo do que em apenas um processador.

Outro fator relevante é a programação de máquinas paralelas com memória distribuída, como

clusters, que é mais complexa, pois o programador é o responsável por orquestrar toda a troca

de mensagens entre os processadores quando eles estiverem resolvendo um problema em comum mediante um algoritmo paralelo. Já a programação de máquinas paralelas com a memória compartilhada por todos os processadores segue um paradigma de programação significativamente mais próximo daquele usado em máquinas convencionais. A programação desses sistemas é considerada mais fácil do que daqueles onde as máquinas se comunicam por troca de mensagens.

Mas é possível construir um sistema que tenha memória compartilhada usando uma máquina com memória distribuída, ou seja, simular, por software, uma memória compartilhada por intermédio da rede de comunicação de dados, como é feito, por exemplo, no TreadMarks [Amza96]. Neste sistema de memória compartilhada distribuída implementada em software

(16)

(Software Distributed Shared Memory – S-DSM) existe uma memória distribuída, constituída pelas memórias de cada um dos processadores, que pode ser acessada diretamente por todos os processadores da máquina paralela. TreadMarks usa a infra-estrutura do sistema de memória virtual para implementar a memória compartilhada; assim, a granularidade da memória compartilhada é uma página.

No TreadMarks, a memória local (física) de cada processador forma um cache no espaço de endereços da memória virtual compartilhada. Se um processador acessa uma página compartilhada que não está mapeada na sua memória local, ocorrerá uma falha de página (page fault), que será detectada pelo sistema de memória virtual. Nesse momento, o TreadMarks traz um cópia atualizada da página compartilhada, à partir de sua localização remota, para dentro da memória local e reinicia o acesso que causou a falha de página. Dessa maneira, um espaço de endereçamento de memória compartilhado pelos diversos processadores do cluster é implementado. Para manter a consistência dos dados neste espaço de memória compartilhado, no caso de escritas a quaisquer das páginas compartilhadas, mensagens de invalidação de página devem ser enviadas a todos os processadores que têm cópia das páginas acessadas para escrita. Mas estas mensagens de invalidação não podem ser enviadas a cada escrita já que, neste caso, a freqüência do envio destas mensagens seria, em muitos casos, muito elevada. Por essa razão, em sistemas S-DSM como o TreadMarks, as mensagens de invalidação só são enviadas em momentos específicos de sincronização, a partir dos quais o estado da memória compartilhada precisa estar coerente em todos os processadores para a correta execução do código paralelo.

Sistemas baseados no modelo de memória compartilhada distribuída exigem que mecanismos eficientes de sincronização sejam implementados. Entretanto, a implementação de tais mecanismos exige comunicação entre os diferentes processadores, isto é, troca de mensagens. A troca de mensagens, por sua vez, é realizada por intermédio da rede de comunicação de dados que interliga as estações de trabalho, gerando tráfego nessa rede que pode estar competindo com outros tráfegos relevantes. Além disso, as mensagens relativas à sincronização são submetidas às várias camadas de protocolos presentes na rede de comunicação de dados, recebendo tratamento equivalente ao dado às mensagens de dados úteis ou não ao processo, o que pode provocar atrasos na comunicação que implementa a sincronização.

(17)

Pesquisadores do Departamento de Informática da UFES, em parceria com pesquisadores da COPPE/UFRJ, desenvolveram uma rede auxiliar de sincronização que foi usada para a implementação, em hardware, de um Relógio Global [DeSouza03]. Relógios Globais são componentes fundamentais em ferramentas de análise e depuração de código paralelo. Com eles podemos mapear no tempo um evento relevante de uma computação, mesmo quando esse evento ocorre em processadores distintos [Meira_Jr96].

O Relógio Global implementado é formado por uma estrutura em árvore composta por duas unidades dispostas hierarquicamente, o Nó e o Sincronizador, conforme ilustrado na Figura 1.1. Sincronizador Intermediário outros Nós Processadores outros Nós Processadores Nó Processador contador Sincronizador de Topo gerador de pulsos outros Sincronizadores Intermediários Nó Processador contador Nó Processador contador Nó Processador contador Sincronizador Intermediário Sincronizador Intermediário outros Sincronizadores Intermediários Sincronizador Intermediário outros Nós Processadores outros Nós Processadores Nó Processador contador Nó Processador contador Sincronizador de Topo gerador de pulsos outros Sincronizadores Intermediários Nó Processador contador Nó Processador contador Nó Processador contador Nó Processador contador Nó Processador contador Nó Processador contador Sincronizador Intermediário Sincronizador Intermediário outros Sincronizadores Intermediários

Figura 1.1: Relógio Global implementado em hardware.

O Nó é a unidade de menor hierarquia e contém um contador que guarda o valor do Relógio a cada instante. Cada processador do cluster tem um Nó ligado diretamente ao seu barramento

Peripheral Component Interconnect - PCI [PCISIG98] e, do lado da rede, o Nó tem uma

conexão com um Sincronizador por intermédio de cabo específico. O Sincronizador é uma unidade de concentração e controle à qual se conectam Nós ou outros Sincronizadores. No protótipo de Relógio Global desenvolvido está prevista a utilização de um a três níveis de Sincronizadores. Os Sincronizadores participantes do segundo ou do terceiro níveis são ditos Sincronizadores Intermediários e o Sincronizador de primeiro nível é dito Sincronizador de

(18)

Topo. Cada Sincronizador Intermediário possui oito portas down para comunicação com o nível inferior da hierarquia, e uma porta up para comunicação com o nível superior da hierarquia. O Sincronizador de Topo tem configuração física idêntica ao Sincronizador Intermediário, exceto por: não contemplar a porta up; gerar os pulsos de incremento dos contadores dos Nós (que formam o Relógio Global); e concentrar os sinais de reinicialização do Relógio Global, que podem ser gerados por qualquer Nó, e enviá-los sincronamente para todos os Nós do Relógio Global. Para se constituir um sistema, é mandatária a presença de um Sincronizador de Topo e, pelo menos, dois Nós de processamento. O sistema poderá acomodar de um até 73 Sincronizadores, e de dois até 512 Nós.

Como ilustrado na Figura 1.2 , a rede do Relógio Global trabalha em paralelo com a rede de comunicação de dados do cluster. A rede de comunicação de dados permanece com sua função nobre de transferência de dados úteis à computação, enquanto a rede auxiliar assume a responsabilidade de transferir, com maior desempenho, os sinais necessários ao funcionamento do Relógio Global.

Rede de interconexão de dados convencional Rede auxiliar de sincronização IRS IRD NP0 IRS IRD NP1 IRS IRD NPn-2 IRS IRD NPn-1

IRD Interface de rede de dados IRS Interface de rede de sincronização

NP Nó processador

Rede de interconexão de dados convencional Rede auxiliar de sincronização IRS IRD NP0 IRS IRD NP0 IRS IRD NP1 IRS IRD NP1 IRS IRD NPn-2 IRS IRD NPn-2 IRS IRD NPn-1 IRS IRD NPn-1

IRD Interface de rede de dados

IRD Interface de rede de dados IRSIRS Interface de rede de sincronizaçãoInterface de rede de sincronização

NP Nó processador

NP Nó processador

Figura 1.2: Ilustração de um cluster com a rede auxiliar de sincronização.

No entanto, a rede auxiliar do Relógio Global pode ser usada para implementar primitivas de sincronização, tais como barreiras, locks, etc, que são importantes para a implementação de sistemas de memória compartilhada distribuída.

(19)

1.1 MOTIVAÇÃO

Os sistemas S-DSM implementados totalmente em software fazem uso da rede de comunicação de dados para a troca de mensagens de sincronização essencial ao seu funcionamento, sendo que a sobrecarga de comunicação gerada é um fator limitante do desempenho desses sistemas. A observação desta deficiência nos motivou a investigar a implementação, em hardware, de mecanismos de sincronização distribuída. Assim, cada processador faria uso de uma rede auxiliar de sincronização, funcionando de forma independente da rede de comunicação de dados, para transmissão de mensagens relativas à sincronização.

1.2 OBJETIVOS

O objetivo do trabalho de pesquisa apresentado nesta dissertação foi a implementação e a avaliação do desempenho de mecanismos de sincronização em hardware desenvolvido por nós, frente a esses mesmos mecanismos implementados na forma tradicional, unicamente por

software.

Com estes mecanismos implementados em hardware esperamos obter melhora significativa no desempenho dos sistemas de memória compartilhada distribuída, tendo em vista que dois importantes fatores que influenciam negativamente no tempo de execução de programas paralelos nesse modelo serão eliminados:

• As mensagens de sincronismo não mais estarão submetidas às várias camadas de protocolos presentes na rede de comunicação de dados;

• Não ocorrerá concorrência na rede de comunicação de dados entre as mensagens de sincronização e a comunicação de dados verdadeiramente útil ao processo.

1.3 CONTRIBUIÇÕES

As principais contribuições deste trabalho de pesquisa são:

• Desenvolvimento, implementação e validação de mecanismos de sincronização

distribuída implementados em hardware.

(20)

Disponibilização de hardware simples, de baixo custo e otimizado para transmissão de mensagens de sincronismo em sistemas de memória compartilhada distribuída.

1.4 ORGANIZAÇÃO DA DISSERTAÇÃO

Esta dissertação está organizada em sete capítulos. Após esta introdução, o Capítulo II apresenta uma visão geral sobre mecanismos de sincronização. O Capítulo III descreve, de forma detalhada, a implementação em hardware dos mecanismos de sincronização distribuída eleitos para este fim durante o desenvolvimento deste trabalho de pesquisa. O Capítulo IV apresenta o método utilizado para a avaliação. O Capítulo V contém os experimentos desenvolvidos. O Capítulo VI apresenta os trabalhos correlatos, a análise crítica deste trabalho e as oportunidades para sua melhoria. O Capítulo VII apresenta as conclusões e as indicações para trabalhos futuros.

(21)

Iniciaremos apresentando características gerais de máquinas paralelas e, em seguida, trataremos de processos e comunicação entre processos. Finalmente, apresentaremos os mecanismos de sincronização de processos disponíveis atualmente.

2.1 MÁQUINAS PARALELAS

Nos últimos anos, o paralelismo tem sido aplicado como a principal solução para a elevação do desempenho de computadores. A pesquisa de novas tecnologias possibilitou o surgimento de diversos tipos de máquinas paralelas, no entanto, a sua efetiva utilização tem sido dificultada devido à sua maior complexidade de programação em relação às máquinas seqüenciais.

Em 1966, Flynn [Flynn66] propôs uma taxonomia para máquinas paralelas. Esta contempla quatro classes de máquinas, descritas a seguir, conforme o nível de paralelismo com que um processador da máquina trata suas instruções e dados.

SISD (Single Instruction stream Single Data stream) – As máquinas puramente seqüenciais se enquadram nesta categoria.

SIMD (Single Instruction, Multiple Data) – Cada processador executa a mesma instrução manuseando dados distintos. Computadores com arquitetura vetorial [Patterson03, Ap. G] se enquadram nesta categoria.

MISD (Multiple Instruction, Single Data) – Não houve exploração comercial

significativa desta categoria até o momento.

MIMD (Multiple Instruction, Multiple Data) – Cada processador trata suas próprias instruções e opera seus próprios dados.

Dentre as máquinas mencionadas, as MIMD emergiram nos últimos anos como as eleitas para o processamento paralelo de propósito geral. Dois fatores se destacam como responsáveis por essa realidade. O primeiro deles é a flexibilidade. Uma máquina paralela com arquitetura MIMD pode funcionar como um multiprocessador monousuário para obter alto desempenho na execução de aplicações mono-tarefa, multi-tarefa ou, ainda, executando uma combinação

(22)

destes dois tipos de aplicação. O segundo fator é a possibilidade de se utilizar microprocessadores comerciais, ditos de prateleira, na construção deste tipo de máquina paralela. Na verdade, praticamente a totalidade das máquinas paralelas MIMD fabricadas atualmente utiliza microprocessadores usualmente encontrados em estações de trabalho e servidores monoprocessados [Patterson03].

A arquitetura de memória é uma característica importante a ser observada em máquinas paralelas (deste ponto em diante usaremos o termo máquinas paralelas como sinônimo de máquinas paralelas MIMD). A organização física da memória segrega as máquinas paralelas em máquinas com memória centralizada compartilhada e máquinas com memória fisicamente distribuída. A comunicação entre processadores de máquinas paralelas com memória distribuída pode ser implementada mediante espaço de endereçamento compartilhado, conhecido como sistemas com memória compartilhada distribuída (Distributed

Shared-Memory – DSM), ou por intermédio de troca de mensagens, quando não existe espaço de

endereçamento compartilhado.

Máquinas com memória centralizada compartilhada podem ser implementadas como sistemas em que a memória está organizada como um bloco único, e de tal forma que todos os processadores acessam as posições de memória desse bloco único em tempo uniforme. Nestes sistemas, para a interligação entre processadores e memória é comum a utilização de um barramento. Para um número elevado de processadores (tipicamente, maior que 16) são utilizados barramentos múltiplos ou mesmo um hardware de comutação, sem prejuízo da característica principal da arquitetura, que é o acesso à memória com tempo uniforme, por qualquer processador. Essas máquinas são popularmente conhecidas como multiprocessadores simétricos (Symetric Multiprocessors – SMPs) e essa arquitetura de memória é conhecida como memória de acesso uniforme (Uniform Memory Access – UMA). Porém, a construção de máquinas UMA com elevado número de processadores torna-se complexa devido ao gargalo que se forma na comunicação entre os vários processadores e a memória. Atualmente, muitos trabalhos de pesquisa estão sendo desenvolvidos com base nessa classe de máquinas. A exploração do paralelismo é facilitada pela simplicidade de manutenção de dados globais e pela possibilidade de comunicação entre processos via memória. Os acessos concorrentes à memória são coordenados por primitivas de sincronização. A Figura 2.1 (página 21) ilustra de forma simplificada este tipo de máquina. Na figura temos os processadores com seus

(23)

respectivos caches, a memória principal, o sistema de entrada e saída e o mecanismo de interligação. Processador Um ou mais níveis de cache

Memória principal Sistema de E/S Processador Um ou mais níveis de cache Processador Um ou mais níveis de cache Processador Um ou mais níveis de cache Mecanismo de interligação Processador Um ou mais níveis de cache

Memória principal Sistema de E/S Processador Um ou mais níveis de cache Processador Um ou mais níveis de cache Processador Um ou mais níveis de cache Mecanismo de interligação

Figura 2.1: Estrutura básica de um multiprocessador com memória centralizada compartilhada - adaptada de [Patterson03, p.531].

Máquinas com memória distribuída são sistemas em que a memória está fisicamente distribuída. Nesse arranjo, cada processador tem sua própria memória local. Como o espaço de endereçamento de memória consiste de vários espaços separados fisicamente, um processador não pode endereçar diretamente o espaço de endereçamento de memória de outro. Um mesmo endereço físico de memória utilizado em processadores diferentes refere-se a diferentes localizações em memórias distintas. Cada conjunto - processador e memória - funciona como um computador autônomo e, por esse motivo, estas máquinas são conhecidas como multicomputadores. Nessa arquitetura de memória, o tempo de acesso depende da localização do dado na memória física. Como este tempo de acesso não é uniforme, esta arquitetura se enquadra no modelo conhecido como Nonuniforme Memory Access – NUMA. A simplicidade de implementação e a ausência de barramentos para interconexão de vários processadores a uma memória centralizada, tipicamente de alto custo, são vantagens

(24)

apresentadas por essas arquiteturas, quando comparadas com as arquiteturas UMA. A Figura 2.2 (página 22) ilustra uma máquina paralela com arquitetura de memória distribuída, onde pode ser observado que cada processador tem sua memória independente e uma interface para uma rede de interconexão que conecta todos os nós processadores.

Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Rede de interconexão Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Rede de interconexão

Figura 2.2: Estrutura básica de um multiprocessador com memória distribuída - adaptada de [Patterson03, p.532].

Máquinas com memória compartilhada distribuída (Distributed Shared-Memory – DSM) são sistemas que oferecem a abstração de um sistema de memória compartilhada, embora o

hardware possua memória distribuída. A memória é percebida pelos processadores como um

bloco único, isto é, dois processadores distintos acessando um mesmo endereço de memória virtual compartilhada apontam para a mesma posição, possibilitando que a troca de dados seja feita por intermédio desta memória. Nesta classe de máquinas, cada processador tem acesso rápido à sua própria memória local, no entanto, caso o dado necessário esteja em uma memória remota, existe o custo de transferência do bloco desejado através da rede de interligação. Um complicador adicional é a coerência de cache, pois a cópia local deve ser invalidada quando houver alteração do bloco original. Existem protocolos que implementam esta coerência no nível do cache [Patterson03]. Estes protocolos envolvem hardware, têm custos e para que eles funcionem bem, a rede de interligação deve ser rápida. A abstração de uma memória única provê ao programador a facilidade de escrita para o modelo de memória compartilhada, tornando sua tarefa menos complexa.

(25)

Um multicomputador também pode ser construído a partir de computadores totalmente separados e conectados por uma rede local (Local Area Network – LAN) e, nesse arranjo, estas máquinas paralelas são chamadas popularmente de clusters. Essa arquitetura é mais vantajosa em termos de complexidade e custo de implementação. Por outro lado, nela os processadores que necessitam de dados que estão na memória local de outro processador têm um tempo de acesso a esses dados bastante diferenciado em relação ao tempo de acesso aos dados que estão na memória local, devido à latência e taxa de transferência da rede de comunicação. Além disso, o desenvolvimento de programas para essa classe de máquinas apresenta maior complexidade, já que o programador precisa orquestrar toda a troca de mensagens entre os processadores.

Na Figura 2.3 podem ser observadas linhas que delimitam cada um dos conjuntos processador, memória, dispositivos de entrada e saída e a interface com uma rede de comunicação externa. A intenção em se destacar os conjuntos é ressaltar que, no caso de

clusters, a máquina paralela é construída a partir da replicação da estrutura de máquinas

convencionais. Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Rede de interconexão Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Processador + cache Memória E/S Rede de interconexão

Figura 2.3: Estrutura básica de um cluster - adaptada de [Patterson03, p.532].

Em clusters cada processador tem o seu espaço privado de memória que não pode ser acessado diretamente por outro processador. Nesse modelo, a comunicação ocorre sempre através da transmissão de mensagens, que requisitam alguma ação ou dado via rede de comunicação. Para que o programador tenha a abstração de uma memória única, é possível usar o paradigma de memória compartilhada distribuída baseado em software (S-DSM).

(26)

Nessa implementação, a coerência dos dados é mantida em nível de página ao invés de em nível de cache, como ocorre em sistemas DSM por hardware. Isso é conseguido utilizando-se o sistema operacional, porém a consistência deve ser preguiçosa, isto é, as páginas não devem ser invalidadas a cada escrita, pois, o compartilhamento falso faria com que a rede de interligação fosse inundada com atualizações desnecessárias de páginas. O compartilhamento falso ocorre quando dois processadores têm dados numa mesma página, mas os dados são acessados de forma independente por cada processador.

Independentemente da arquitetura de memória adotada e do modelo de comunicação utilizado, a intenção de se utilizar máquinas paralelas é diminuir o tempo de execução de programas mediante a sua divisão em partes que possam ser executadas concorrentemente em cada um dos processadores da máquina. Nesse caso, cada parte do programa é denominada processo.

2.2 PROCESSOS

Processo é o conceito mais central em sistemas operacionais e é definido como a abstração de um programa em execução [Tanenbaum00].

Em um sistema multitarefa, o processador alterna a execução de processos, dedicando a cada um deles um tempo da ordem de dezenas a centenas de milisegundos. Essa alternância em um curto espaço de tempo, conhecida como multiprogramação, provoca no usuário a ilusão de que os programas estão sendo executados concorrentemente. Máquinas paralelas podem executar processos concorrentemente, no entanto, freqüentemente é necessário que haja interação entre processos. Um processo em execução pode depender da saída de um outro processo para que possa prosseguir, por exemplo. Nesse caso, quando executando em um mesmo processador, o primeiro processo deve ser suspenso e o segundo, que vai gerar a saída, deve ter sua execução retomada.

Identificamos, então, três estados possíveis para um processo. Ele pode estar executando se, efetivamente, está ocupando o processador naquele instante; pode estar bloqueado, se estiver aguardando por dados ainda não disponíveis; e pode estar pronto para ser executado, caso não dependa de nenhuma entrada para prosseguir sua execução.

Cada processo tem associado a si um espaço de endereçamento em memória, onde se encontram seu código e seus dados. A cada processo está associado também o estado interno

(27)

do processador a cada instante no tempo, representado pelos valores no conjunto de registradores do hardware do processador [Tanenbaum00]. Para que seja viabilizada a alternância entre processos, citada anteriormente, é imprescindível que todas as informações sobre o processo suspenso sejam preservadas em algum lugar. Essas informações serão utilizadas posteriormente, quando o processo for reiniciado, para a restauração das condições exatas em que o mesmo foi suspenso. Assim, tudo se passa como se cada processo possuísse um processador exclusivo para si.

A Figura 2.4 ilustra os estados mencionados e as transições possíveis entre eles. Quando um processo está executando, ele pode ser bloqueado (1) ou passar ao estado pronto (2), dependendo do motivo de sua suspensão. Do estado pronto, o processo pode ser selecionado a qualquer instante e retornar ao estado executando (3). Para que um processo no estado bloqueado seja reiniciado é obrigatória a sua passagem pelo estado pronto (4) [Tanenbaum00]. A parte do sistema operacional responsável por decidir se um processo deve ou não ser executado naquele instante é chamada agendador.

Executando Bloqueado Pronto 2 1 3 4 Executando Bloqueado Pronto 2 1 3 4

Figura 2.4: Estados e transições de um processo - adaptada de [Tanenbaum00, p.49].

2.3 COMUNICAÇÃO ENTRE PROCESSOS

Como visto na seção anterior, a interação entre processos é freqüente e existe uma demanda de comunicação quando há necessidade de compartilhamento ou troca de informações entre eles. Geralmente, essa comunicação é feita por meio de recursos comuns como, por exemplo, a memória do sistema. Essa comunicação deve ser implementada de uma maneira simples e bem estruturada para preservar o desempenho do sistema como um todo.

Para que a comunicação entre processos seja confiável, devemos atentar à forma como um processo deve passar informações para outro, garantir que não haja interferência prejudicial

(28)

entre dois ou mais processos e, também, assegurar que o seqüenciamento adequado seja preservado em situações de dependências [Tanenbaum00].

A comunicação entre processos pode ser feita mediante o compartilhamento de memória principal, de arquivos de dados, troca de mensagens, etc. Uma situação que deve ser evitada é aquela que possa proporcionar uma condição de corrida. Condição de corrida é um comportamento anormal que ocorre quando é assumido incorretamente que um evento sempre acontecerá antes de outro. Uma condição de corrida se configura quando dois ou mais processos acessam dados compartilhados e o resultado da computação depende da ordem em que esses processos são executados. O trecho do programa em que dados compartilhados são acessados é denominado seção crítica ou região crítica. No decorrer da execução de uma seção crítica de código, um processo leva os dados compartilhados a estados intermediários inconsistentes; se um outro processo acessa os dados em um destes estados inconsistentes está caracterizada uma condição de corrida. Para evitarmos condições de corrida devemos assegurar que, se um processo está utilizando uma variável ou arquivo compartilhado, os outros processos serão impedidos de fazer o mesmo.

Em muitos casos em que processos cooperam há obrigatoriedade de que, ao atingir um determinado ponto, um processo pare e espere até que outros processos cheguem nesse mesmo ponto. Essa garantia é conseguida com a introdução de mecanismos de sincronização entre os processos, que serão examinados na próxima seção.

2.4 SINCRONISMO DE PROCESSOS

Sempre que existe comunicação entre dois ou mais processos é necessário que seja implementado algum mecanismo de sincronização para garantir que as ações sobre os dados sejam tomadas numa seqüência temporal válida, dentro de um protocolo de comunicação estabelecido entre as entidades. A seguir, discutiremos mecanismos de sincronização que implementam exclusão mútua.

As implementações de exclusão mútua em hardware mais corriqueiras utilizam a inibição de interrupções e a instrução que testa e configura o bloqueio (Test And Set Lock – TSL). Na primeira técnica, o processo desativa todas as interrupções antes de entrar em sua região crítica e reativa-as imediatamente após a saída. O acesso exclusivo ao dado compartilhado é assegurado, pois o processo não pode ser interrompido em sua região crítica. Essa técnica

(29)

apresenta inconvenientes. Um deles é que não é prudente que processos de usuário tenham poder de desabilitar interrupções. Outro é que desabilitar interrupções por um período longo de tempo pode ser desastroso. E por fim, a solução não funciona em máquinas com vários processadores. A segunda técnica, a instrução TSL, é uma solução em hardware projetada para ambientes com vários processadores. A idéia é simples: O processador que executa a instrução TSL bloqueia o barramento de memória impedindo, assim, que outro processador acesse a memória durante o período de execução da instrução TSL. Essa técnica faz uso de uma variável lock, iniciada com valor 0, isto é, lock livre. A instrução TSL lê lock para um registrador. Se lock livre, TSL ocupa lock armazenando valor diferente de 0 em lock. Se lock ocupado, fica em espera ativa até que seja liberado. As operações de leitura e armazenamento da instrução TSL são executadas atomicamente. Citamos como vantagens dessa solução a simplicidade de uso, a disponibilidade em quase todos os processadores atuais e a aplicabilidade em máquinas paralelas. Além disso, não é concedido aos processos de usuários o poder para desabilitar interrupções. As desvantagens na implementação da instrução TSL são a permanência em espera ativa e o risco de um processo sempre encontrar lock ocupado. Algumas tentativas de implementação de exclusão mútua por software com espera ativa foram propostas. Na década de 60, o matemático holandês Dekker propôs a primeira solução correta para o problema de exclusão mútua entre dois processos usada por [Dijkstra65]. Peterson propôs em 1981, uma solução simples e elegante para o problema de exclusão mútua, tornando a solução de Dekker obsoleta [Tanenbaum00]. A Figura 2.5 mostra o algoritmo proposto por Peterson. A novidade é que ao entrar na região crítica, um processo já indica que a vez é do outro, solucionando a inconsistência causada por uma condição de corrida. Antes de entrar em sua região crítica, cada processo chama enter_region, passando seu próprio número de processo como parâmetro. Essa chamada provocará espera até que seja seguro entrar, caso outro processo já esteja na região crítica.

(30)

#define FALSE 0 #define TRUE 1

#define N 2 /* número de processos */

int turn; /* de quem é a vez (turn)? */

int interesded[N]; /* todos os valores inicialmente 0 (FALSE) */ void enter_region(int process); /* o process é 0 ou 1 */

{

int other; /* número dos outros processos */

other = 1 – process; /* o oposto do processo */

interested[process] = TRUE; /* mostra que você está interessado */

turn = process; /* define o sinalizador */

while (turn == process && interested[other] == TRUE; /* declaração nula */ }

void leave_region(int process) /* processo: quem está saindo */ {

interested[process] = FALSE; /* indica saída da região crítica */ }

Figura 2.5: Solução de Peterson para obter exclusão mútua - adaptada de [Tanenbaum00, p.56].

2.4.1 Sleep e Wakeup

As soluções apresentadas até aqui contêm um redutor de desempenho que é a espera ativa. Sempre que um processo não tem permissão para entrada em sua região crítica, ele entra em laço improdutivo de espera, consumindo desnecessariamente, tempo de processador. Existem primitivas de comunicação entre processos que, em vez de colocar o processo em espera ativa para aguardar a entrada na sua região crítica, elas bloqueiam esse processo até que a entrada seja permitida, otimizando o uso do processador. O par sleep e wakeup é uma dessas primitivas. Se o processo não tem permissão para entrar na região crítica, ele faz uma chamada de sistema sleep que provoca o seu bloqueio até que outro processo o acorde, mediante uma chamada de sistema wakeup [Tanenbaum00]. Porém, pode ocorrer uma condição em que um processo faça uma chamada de wakeup para um outro que não esteja na condição de bloqueado. Nesse caso, pode ocorrer dos dois processos permanecerem bloqueados indefinidamente. Este comportamento pode ser contornado com a inclusão de bits de controle, porém essa solução apresenta o inconveniente desse número de bits aumentar à medida que cresce o número de processos envolvidos.

2.4.2 Semáforos

Semáforo é um mecanismo de sincronização sugerido por E. W. Dijkstra em 1965. Trata-se de um tipo abstrato de dado composto por um valor inteiro e uma fila de processos, onde duas operações são permitidas – down e up -, que são generalizações das operações sleep e wakeup, vistas na subseção anterior. O valor inteiro armazena o número de chamadas de wakeups

(31)

feitas sem que existissem processos realmente na condição de bloqueados. A chamada down verifica se o valor inteiro armazenado é maior que 0 e, se for, ele é decrementado de 1 e o processo continua normalmente. Por outro lado, se for 0, o processo passa à condição de bloqueado sem completar a operação down naquele instante. A chamada up incrementa de 1 o valor inteiro armazenado no semáforo. Se um ou mais processos encontram-se bloqueados nesse momento, um deles é escolhido e autorizado a completar sua chamada down. Para que semáforos funcionem corretamente, é imprescindível que as operações sejam atômicas. Uma vez que um semáforo tenha iniciado, nenhum outro processo pode acessá-lo sem que ele tenha sido finalizado ou bloqueado. Então, quando utilizamos múltiplos processadores com memória compartilhada, é necessário proteger o semáforo com uma variável de bloqueio que utilize a instrução TSL para assegurar que apenas um processador consulte o semáforo por vez. A utilização de semáforos exige cuidados especiais na programação, pois, um deslize simples pode conduzir a situações imprevisíveis [Oliveira01,Tanenbaum00].

2.4.3 Monitores

Monitores são primitivas de sincronização de mais alto nível que proporcionam uma maneira mais fácil de obter exclusão mútua. Proposto por Hoare e Brinch Hansen, um monitor é uma coleção de variáveis ,de procedimentos e de estruturas de dados que são agrupados em um tipo especial de módulo ou de pacote [Tanenbaum00]. Uma característica importante é que apenas um processo pode estar ativo em um monitor em qualquer instante. É comum que as primeiras instruções de um procedimento de monitor verifiquem se existe outro processo ativo dentro do monitor naquele momento. Caso haja, o processo de chamada será bloqueado até que o processo ativo tenha deixado o monitor. O bloqueio dos processos é implementado através da introdução de variáveis de condição em conjunto com 2 operações – wait e signal – sobre elas, conforme [Tanenbaum00]. Os compiladores reconhecem um monitor e gerenciam chamadas para procedimentos dele de forma diferenciada em relação a outras chamadas de procedimentos, cabendo a eles implementar a exclusão mútua.

Monitores, assim como os semáforos, foram projetados para resolver o problema de exclusão mútua em um ou mais processadores que acessam a uma memória comum. Eles não são aplicáveis a sistemas com múltiplos processadores com memória distribuída [Tanenbaum00].

(32)

2.4.4 Passagem de Mensagens

Como vimos acima, semáforos e monitores são baseados no compartilhamento de variáveis. Esse fato implica no compartilhamento de memória. Entretanto, quando o sistema é formado por máquinas individuais, separadas fisicamente, não existe o compartilhamento de memória. Passagem de mensagem é um paradigma usado em máquinas paralelas distribuídas, onde a sincronização e a comunicação entre os processos são baseadas nas primitivas send e receive. Em linhas gerais, a primitiva send envia uma mensagem para um determinado processo de destino e a primitiva receive recebe uma mensagem de um determinado processo de origem [Tanenbaum00].

São possíveis alguns esquemas originados a partir da utilização do conceito de bloqueio combinado com as primitivas send e receive que implementam sincronização. Em um deles –

blocking send, blocking receive -, conhecido como “rendezvous” (encontro), emissor e

receptor ficam bloqueados até que a mensagem seja entregue. Noutro esquema – nonblocking

send, blocking receive -, o emissor continua processando normalmente após enviar e o

receptor permanece bloqueado até que a mensagem seja recebida. Apesar de alguns problemas conduzirem ao consumo demasiado de recursos, este é o esquema mais utilizado. Outro esquema utilizado – nonblocking send, nonblocking receive -, pressupõe que nenhuma das partes envolvidas na comunicação precisa esperar.

2.4.5 Barreiras

Barreira é uma primitiva de sincronização utilizada em processamento paralelo no modelo de memória compartilhada. Aplicada a um grupo de processos, a barreira tem a propriedade de não permitir que um processo siga adiante, a menos que todos os outros membros do grupo ao qual ele pertence também tenham alcançado a barreira. A presença da barreira sincroniza os processadores e evita que, por exemplo, uma posição de memória seja lida antes que o dado correto tenha sido devidamente escrito por outro processador. As barreiras ocorrem na ordem empregada dentro do programa.

2.4.6 Locks

Lock é uma primitiva de sincronização utilizada quando se configura uma situação de

exclusão mútua. O lock indica a sincronização entre dois processadores: o que detém o lock e o que está requisitando aquele mesmo lock. Dessa forma, o processador requisitante deve

(33)

aguardar até que o lock seja liberado pelo processador que o detém para, então, entrar na seção crítica. Locks diferentes podem ser usados por processadores diferentes e nada se pode dizer com relação à ordenação deles dentro de um programa.

2.4.7 Broadcast

Broadcast é uma primitiva de sincronização utilizada para a disseminação de informações em

sistemas distribuídos. Por exemplo, um processador pode utilizar esta primitiva para informar aos outros processadores que uma determinada página compartilhada de memória foi alterada e, por conseqüência, está inválida no TreadMarks.

(34)

Este Capítulo descreve a implementação em hardware dos mecanismos de sincronização distribuída que desenvolvemos. Apresentamos os mecanismos, suas características construtivas e funcionais, assim como a descrição dos seus elementos de hardware e biblioteca de software de acesso.

3.1 OS MECANISMOS DE SINCRONIZAÇÃO ELEITOS

Investigamos os mecanismos de sincronização distribuída necessários para a implementação de S-DSM e avaliamos a importância e a viabilidade de implementação em hardware de um subconjunto deles. Nossas avaliações nos conduziram a implementar dois mecanismos de sincronização: barreira e lock. Estes mecanismos são suportados por uma rede auxiliar, paralela à rede de dados, concebida inicialmente como parte de um Relógio Global implementado em hardware [DeSouza03]. Acreditamos que o ganho de desempenho de um sistema real com esses mecanismos implementados em hardware, medido com relação à sistemas tradicionais com implementação por software e empregando a rede de dados, será significativo.

Para a implementação desses mecanismos é necessário que a rede auxiliar de sincronização esteja capacitada a transmitir dois tipos de mensagens relativas ao mecanismo barreira e dois tipos de mensagens relativas ao mecanismo lock. Com o objetivo de melhor aproveitar o

hardware desenvolvido, implementamos também duas mensagens complementares: reset e broadcast. A mensagem reset foi implementada para a inicialização do Relógio Global. A

mensagem de broadcast foi concebida com o propósito de prover o sistema de um mecanismo de difusão de mensagens para uso geral.

3.2 ESPECIFICAÇÃO DAS MENSAGENS

A rede de auxiliar de sincronização é uma rede hierárquica que opera por intermédio de mensagens enviadas pelos processadores da máquina paralela através dos elementos Nó da rede; a Figura 3.2 (página 35) apresenta a rede de forma esquemática. As mensagens possuem um número variável de bits, e são transmitidas através de linha física cujo nível lógico de repouso é igual a 0. A Figura 3.1 ilustra o formato geral das mensagens.

(35)

Como apresentado na Figura 3.1, uma mensagem é composta por bits de controle de comunicação, de comando e de dados. O início de uma mensagem é detectado pela rede através da transição, na linha física, do nível de repouso para o nível lógico 1, o que caracteriza o bit de controle start bit de uma mensagem. Após o start bit, são enviados três

bits de comando que carregam o código da mensagem, isto é, que indicam que operações

devem ser executadas pela rede ao receber aquela mensagem. Em seguida ao comando são enviados bits de dados. O número de bits é variável, podendo ir de zero a 76 bits. Uma mensagem termina com o bit de controle stop bit, que retorna a linha de comunicação ao seu estado de repouso.

1 C0 C1 C2 D0 D1 Dn 0

start bit comando dados stop bit

1 C0 C1 C2 D0 D1 Dn 0

start bit comando dados stop bit

Figura 3.1: Formato geral das mensagens.

A rede comporta oito tipos de mensagem, dos quais seis estão especificados e dois estão reservados para uso futuro. A seguir, descrevemos as mensagens com os respectivos códigos, nomes e funções (os valores binários dos códigos foram escolhidos arbitrariamente).

000 = reset. Inicializa o Relógio Global. Este comando sobe na hierarquia de Sincronizadores

e, ao chegar ao topo, desce, inicializando todos os contadores do Relógio Global ao chegar de forma síncrona em cada um dos Nós. A mensagem reset não possui campo de dados.

001 = barrier. Cria uma barreira. O campo de dados carrega o código e a máscara da barreira.

O código da barreira tem tamanho igual a oito bits; assim o número máximo de barreiras simultâneas possível é igual a 256. A máscara da barreira informa quais dispositivos participam dela. Seu tamanho pode ser 8, 16 ou 24 bits, dependendo se a rede tem um, dois ou três níveis hierárquicos de sincronizadores (ver Figura 3.2, página 35). Os primeiros oito bits após o código da barreira indicam quais Nós, que estão conectados ao mesmo Sincronizador do Nó que está enviando a mensagem, estão participando daquela barreira. Os oito bits intermediários indicam quais Sincronizadores do primeiro nível da rede composto unicamente

(36)

de Sincronizadores participam da barreira. De maneira análoga, o terceiro conjunto de oito

bits indica quais Sincronizadores do nível seguinte da rede de Sincronizadores participam da

barreira. Essa mensagem trafega até o topo da rede, configurando a barreira em toda a rede. Todos os Nós participantes de uma barreira enviam uma mensagem de criação, embora apenas a primeira delas trafegue até o topo da rede - os Sincronizadores que já conhecem uma barreira não propagam as mensagens de criação para níveis acima na hierarquia.

010 = barrier reaching. Informa a um Sincronizador que uma barreira específica foi atingida.

Um byte de dados indica qual é a barreira. Quando todos os Nós conectados a um determinado Sincronizador atingem uma barreira, este Sincronizador informa ao Sincronizador acima dele na hierarquia que aquela barreira foi alcançada por todos os Nós nos níveis imediatamente abaixo do Sincronizador associados ao link de onde veio a mensagem. Quando o Sincronizador no topo da hierarquia recebe esta mensagem uma barreira foi completada por todos os Nós que fazem parte dela; neste caso o Sincronizador de topo transmite uma mensagem do mesmo tipo, 010 – barrier reaching -, com o código da barreira, informando a todos os Sincronizadores e Nós que a barreira foi completada.

011 = broadcast. Dissemina uma mensagem com campo de dados de 76 bits de tamanho por

toda a rede. Diferente do campo de dados das outras mensagens, o campo de dados da mensagem 011 - broadcast é de uso livre por parte do usuário. O número de bits de dados desta mensagem (76) foi escolhido para permitir acomodar: três bits de caracterização dos dados, nove bits para o número do processador emissor da mensagem e 64 bits para os dados de interesse. A mensagem sobe até o topo da hierarquia e depois desce, atingindo a todos os Nós simultaneamente, onde os 76 bits de dados são disponibilizados para cada um dos processadores da máquina paralela.

101 = lock acquire. Solicita a posse de um lock. O campo de dados carrega o código do lock e

o número do processador solicitante. O código do lock tem tamanho igual a oito bits. Assim, o número máximo de locks possível é igual a 256. O número do processador tem nove bits de tamanho, o que limita em 512 o número de Nós presentes na rede. Uma solicitação de lock trafega até o topo da rede. Se lá o Sincronizador verificar que este lock está livre, ele envia uma mensagem do tipo 101 – lock acquire – no sentido inverso, informando a todos os Nós qual deles detém aquele lock naquele instante.

(37)

110 = lock release. Libera um lock. Os oito bits de dados identificam qual lock foi liberado.

Esta mensagem trafega até o topo da rede e retorna, informando a todos os Nós que aquele

lock está livre.

Para enviar uma mensagem, o processador do Nó escreve na interface PCI em endereços específicos. Para saber se uma barreira específica foi alcançada, o processador do Nó lê de uma faixa de 256 endereços no PCI (o barramento PCI pode ser mapeado em memória [PCISIG98]), onde cada um corresponde a uma barreira. Para saber se um determinado lock está livre ou concedido, o processador do Nó lê de uma faixa de 256 endereços, onde cada um corresponde a um lock. Para obter as mensagens de broadcast, o processador do Nó lê de uma faixa de 1024 posições, onde cada uma delas corresponde a uma mensagem de broadcast específica.

3.3 A TOPOLOGIA DA REDE

A Figura 3.2 mostra a estrutura da rede de sincronização que implementamos. Pode-se observar que se trata de uma topologia do tipo árvore, composta por um Sincronizador de Topo, Sincronizadores Intermediários, Nós e cabos de interconexão. Estes elementos estão dispostos hierarquicamente em até quatro níveis na implementação atual, sendo que o Sincronizador de Topo ocupa o nível um, de maior hierarquia, e os Nós podem ocupar os níveis dois, três ou quatro, dependendo do tamanho da rede.

S .T. S .I. S .I. N ó N ív el 1 N ív el 2 N ív el 3 N ív el 4 S .I. N ó S .I. S .I. N ó S .I. N ó

S .T. S incronizador de T opo S .I. S incronizador In term ediári o N ó N ó processador

0 7 504 5 11 0 7 5 6 6 3 0 7 S .T. S .I. S .I. N ó N ív el 1 N ív el 2 N ív el 3 N ív el 4 S .I. N ó S .I. S .I. N ó S .I. N ó

S .T. S incronizador de T opo S .I. S incronizador In term ediári o N ó N ó processador

0 7 504 5 11

0 7 5 6 6 3

0 7

Figura 3.2: Topologia da Rede Auxiliar de Sincronização. Cada Sincronizador possui uma porta up (para cima) e oito portas down (para baixo). A rede mínima possui dois Nós e um Sincronizador e, na implementação corrente, a rede máxima possui 4 níveis (como acima), com um Sincronizador de Topo, 8 sincronizadores no nível 2 e 64 no nível 3 (73 Sincronizadores); os Sincronizadores são independentes mas, correntemente, são alimentados através de slots PCI de máquinas quaisquer. Cada Nó é conectado a um slot PCI de cada um dos computadores que compõem o cluster servido pela rede. Correntemente, o número máximo de Nós é igual a 512.

(38)

A presença do Sincronizador de Topo é obrigatória para a implementação da rede auxiliar de sincronização. Ele é o elemento central na difusão das mensagens da rede e tem como função principal controlar as solicitações oriundas dos Nós no que tange a criação e liberação de barreiras e concessão e liberação de locks. Também é função do sincronizador de Topo prover o sinal de relógio que sincroniza os dispositivos da rede. O Sincronizador de Topo conecta-se a até oito Sincronizadores Intermediários, ou diretamente a até oito Nós, mediante portas de comunicação serial especiais de alta velocidade e dos cabos de interconexão. Não é permitido que estejam conectados ao Sincronizador de Topo, simultaneamente, Sincronizadores Intermediários e Nós. Generalizando, um nível sempre é composto de dispositivos de mesma natureza. Se existem Nós conectados diretamente ao Sincronizador de Topo, significa que a rede é composta por no mínimo dois e no máximo oito Nós.

Sincronizadores Intermediários podem ocupar os níveis hierárquicos dois e três da rede auxiliar. Além de possibilitar expansão do número de Nós da rede, estes dispositivos também têm a função de controlar as solicitações oriundas dos dispositivos do nível hierárquico imediatamente inferior conectados a eles, no que diz respeito à criação e liberação de barreiras. Os Sincronizadores Intermediários conectam-se ao nível imediatamente superior na hierarquia da rede, que pode ser um Sincronizador de Topo ou outro Sincronizador Intermediário, através de porta de comunicação serial especial de alta velocidade e de cabo de interconexão. Conectam-se aos dispositivos do nível hierárquico imediatamente inferior, que podem ser Sincronizadores Intermediários ou Nós, fazendo uso de oito portas de comunicação serial e dos cabos de interconexão. Esses dispositivos podem atingir o número máximo de 72 elementos na rede

Nós são os dispositivos da base da hierarquia e são instalados nas estações de trabalho. Conectam-se ao nível imediatamente superior - Sincronizador Intermediário ou Sincronizador de Topo – utilizando uma porta de comunicação serial especial de alta velocidade e cabo de interconexão. A comunicação com os processadores do cluster servido pela rede de sincronização é feita por intermédio do barramento PCI dos processadores, através do qual cada Nó recebe comandos e disponibiliza informações armazenadas nele para seu processador associado. Permanecem armazenadas no Nó informações sobre as condições das barreiras e dos locks, dados associados a mensagens de broadcast, e também o estado do Relógio Global. A estação de trabalho consulta o Nó para saber se uma barreira específica foi atingida e também para saber se um lock específico está liberado ou concedido e, nesse caso, quem

(39)

mantém a concessão desse lock. Além disso, o Nó mantém em memória as 1024 últimas mensagens de broadcast propagadas pela rede, que podem ser lidas pela aplicação do usuário a qualquer tempo. Os contadores do Relógio Global também podem ser consultados a qualquer tempo. Correntemente, o número máximo de Nós suportados pela rede é 512 (Figura 3.2, página35).

Finalmente, os cabos de interconexão têm a função de interligar fisicamente os dispositivos da rede e transportar os sinais elétricos entre estes. São cabos formados por quatro pares de fios trançados (por par), finalizados em ambas as extremidades com conectores RJ45 (conector especial de rede de dados de 100Mb/s). Como a freqüência de operação da rede é alta - 64 MHz -, algumas precauções são necessárias para que o sistema não sofra com interferências eletromagnéticas e atenda às restrições de tempo de propagação dos sinais de comunicação, que serão mostradas na Subseção 3.4.4 . Essas precauções incluem a utilização de cabos com o mesmo comprimento físico e conectores, assim como os cabos, protegidos por blindagem eletromagnética. A variação do tamanho dos cabos está associada aos tempos de setup e hold da FPGA utilizada na implementação do hardware e ao período do clock de controle deste

hardware (ver detalhes nas próximas subseções). Os dispositivos internos da FPGA exigem

que uma transição nas mensagens manipuladas por eles ocorra em um tempo no mínimo igual ao tempo de setup antes do clock da FPGA e após um tempo no mínimo igual ao tempo de

hold após o clock da FPGA, como ilustrado na Figura 3.3.

ts th CLK

Entrada

CLK – Sinal de clock

Entrada – Sinal de entrada na FPGA

ts– Tempo de setup th– Tempo de hold ts th CLK Entrada CLK – Sinal de clock

Entrada – Sinal de entrada na FPGA

ts– Tempo de setup

th– Tempo de hold Figura 3.3: Diagrama de tempo de setup e hold.

Referências

Documentos relacionados

Poderão também inscrever-se no processo seletivo candidatos em fase de conclusão de curso de graduação, para os candidatos ao Curso de Mestrado, e em fase de conclusão de

Partindo do conceito de Barbieri (2007), pode-se afirmar que, a gestão ambiental é uma prática muito recente, que vem ganhando espaço nas institui- ções públicas e

O Vestibular 2015.1 da Facene tem caráter classificatório, pela ordem decrescente da média ponderada obtida pelo candidato na prova; e caráter eliminatório, se o

Monitor Produtor 1 Produtor 2 Produtor 3 Consumidor 1 Consumidor 2 FilaCheia FilaVazia wait() signal() wait() signal() Monitor Fila Procedure inserir Procedure remover

O que estamos notando a esta altura da análise, é uma ruptura entre ontologia e oikonomia, entre Reino e Governo, exatamente porque podemos perceber que por um lado na

Essa técnica é trabalhada por meio de uma função objetivo em que se pretende encontrar a solução ótima (como o custo, o peso, a área da seção transversal ou qualquer outro

(CESPE Ð TŽcnico Judici‡rio Ð TŽcnico de enfermagem Ð MPU Ð 2010) As cŽlulas musculares agrupam-se em feixes para formar as massas macrosc—picas que recebem o nome

• Porque o eixo de lâminas pode atingir os próprios cabos de ligação, deve segurar a ferramenta elétrica nas superfícies de punho isoladas.O contacto com um cabo sob tensão