Pontifícia Universidade Católica de São Paulo

Tamanho: px
Começar a partir da página:

Download "Pontifícia Universidade Católica de São Paulo"

Transcrição

1 Pontifícia Universidade Católica de São Paulo PUC-SP Everaldo Lopes Silva Proposta de uma infraestrutura de baixo custo com multiprocessamento e utilizando software aberto Mestrado em tecnologias da inteligência e design digital São Paulo 2012

2 Pontifícia Universidade Católica de São Paulo PUC-SP Everaldo Lopes Silva Proposta de uma infraestrutura de baixo custo com multiprocessamento e utilizando software aberto Mestrado em tecnologias da inteligência e design digital Dissertação apresentada à Banca Examinadora da Pontifícia Universidade Católica de São Paulo, como exigência parcial para obtenção do título de Mestre em Tecnologias da Inteligência e Design Digital sob a orientação do Prof. Dr. Demi Getschko. São Paulo 2012

3 FICHA CATALOGRÁFICA AUTORIZO A CÓPIA E DIVULGAÇÃO TOTAL OU PARCIAL DESTE DOCUMENTO PARA FINS DE ESTUDO OU ACADÊMICOS, DESDE QUE CITADA A FONTE. LOPES SILVA, Everaldo. Proposta de uma infraestrutura de baixo custo com multiprocessamento e utilizando software aberto / Everaldo Lopes Silva; orientador Demi Getschko. -- São Paulo, f. Dissertação (Mestrado). Área de Concentração: PUC-SP - TIDD. 1. Inteligência Coletiva CDD. iii

4 Everaldo Lopes Silva PROPOSTA DE UMA INFRAESTRUTURA DE BAIXO CUSTO COM MULTIPROCESSAMENTO E UTILIZANDO SOFTWARE ABERTO Este trabalho refere-se à infraestrutura que seria um conjunto computadores/rede de comunicação onde se executaria sistemas de inteligência e Design Digital dentro do Programa de Estudos Pós-Graduados em Tecnologias da Inteligência e Design Digital - TIDD, com área de concentração em Inteligência Coletiva, da Pontifícia Universidade Católica de São Paulo PUC/SP. APROVADO em: / / PROF. DR. DEMI GETSCHKO PUC-SP (ORIENTADOR) BRASIL iv

5 A meus pais, por iniciarem-me no interesse pela leitura e estudo; OFEREÇO Aos professores, colegas e a Edna da Secretaria do TIDD; DEDICO v

6 AGRADECIMENTOS Agradeço ao professor Dr. Demi Getschko pelos conselhos, sobretudo, os questionamentos que fizeram refletir sobre o conteúdo desse trabalho e o posicionamento do mesmo dentro do cenário da Tecnologia da Informação atual. vi

7 ... buscai diligentemente e ensinai-vos uns aos outros palavras de sabedoria; sim nos melhores livros buscai palavras de sabedoria; procurai conhecimento, sim, pelo estudo e também pela fé." Doutrina e Convênios 88:118 - Ano 1832 vii

8 RESUMO Esta dissertação visa identificar os aspectos técnicos e teóricos que envolvem a utilização de cluster de computadores, tratando especialmente de plataformas com o sistema operacional Linux. Serão apresentados alguns modelos de cluster em Linux, reconhecendo suas vantagens e desvantagens e por fim indicando o modelo escolhido com a devida justificativa. Como parte do trabalho, proporemos um laboratório com um agrupamento de dois equipamentos conectados com duas interfaces de rede gigabit ethernet em cada um e um computador trabalhando isoladamente. Executaremos programas de Inteligência Artificial e Design Digital nesse cluster e compararemos o seu desempenho com apenas um computador executando esses mesmos programas. As medições e análise servirão como base para análise para a verificação se um cluster de Linux seria uma infraestrutura viável em termos técnicos e financeiros para aplicações de Inteligência Artificial e Design Digital. O método de pesquisa será naturalmente a pesquisa experimental e o método de abordagem será indutivo, pois através dos resultados da experimentação e da análise técnica se poderá aplicar o conhecimento obtido em situações semelhantes. Para contextualizar a atividade experimental abordaremos as teorias de pesquisa mais significativas e contemporâneas para que se estabeleça de maneira clara a abordagem científica que norteará o trabalho como um todo. Palavras-chave: Computação, Redes, Sistemas Operacionais, Processamento Distribuído viii

9 ABSTRACT This dissertation has the objective of identifying the technical aspects that deal with the utilization of computer cluster, specially the platforms with Linux operational system. It will be presented some cluster models in Linux, recognizing its advantages and its disadvantages and finally indicating the chosen model with the due justification. As part of this work, we will propose a laboratory with a cluster of two equipments connected with two gigabit interfaces each one and one computer working stand-alone. It will run Artificial Intelligence and Digital Design programs in this cluster, comparing its performance with only one computer running the same programs. The measuring and analysis will indicate if the Linux cluster would be a feasible infrastructure in technical and financial terms for AI and Digital Design application. The research method will be naturally the experimental and the approach method will be inductive, for through the results of the experimentation and technical analysis, it will be able to apply the knowledge achieved in others similar environments. For putting the experimental activity in the correct context, it will be used the more significant and contemporary research theories to establish in a clear way the scientific approach that it will lead the whole work. Keywords: Computation, Networking, Computation, Distributed Systems ix

10 LISTA DE FIGURAS Figura 1 - Codificação de sinal de áudio analógico para sinal de áudio digital Figura 2 - Intercâmbio de pacotes em sistemas multimídia Figura 3 - Intercalamento de pacotes de dados e pacotes multimídia (Interleaving) Figura 4 - Organização de arquivos multimídia não contíguos em discos rígidos Figura 5 - Organização de arquivos multimídia não contíguos em discos rígidos Figura 6 - Comparação entre o modelo ISO/OSI o protocolo TCP-IP Figura 7 - Primitivas send e receive em passagem de mensagens (MPI) Figura 8 - Comunicação entre servidor e cliente em RPC Figura 9 - Memória Compartilhada Distribuída (DSM) Figura 10 - Comunicação entre servidor e cliente em Sockets Figura 11 - Diagrama de blocos simplificado de RPC em Sistema Microsoft Figura 12 - Diagrama de blocos de exemplo de exemplo de RPC em Sistema Microsoft Figura 13 - Digrama de explicativo de Race Passage Figura 14 - Representação de Grafos para resolução do problema do Drink dos Filósofos Figura 15 - Representação da Multiprogamação N-way Figura 16 - Esquema lógico simplificado de um cluster Beowulf Figura 17 - Esquema lógico simplificado de um cluster OSCAR Figura 18 - Esquema lógico do laboratório Figura 19 - Fotografia do laboratório Figura 20 - Medição de banda disponível via Iperf x

11 Figura 21 - Execução das aplicações Breve e PovRay no Nó 00 Figura 22 - Evidência de o cluster estar operacional Figura 23 - Medições de utilização CPU, Memória e Rede no Nó 00 Figura 24 - Tempo de renderização do Benchmark.pov no Nó 00 Figura 25 - Execução da aplicação Breve no Nó 01 Figura 26 - Tempo de renderização do Benchmark.pov no Nó 01 Figura 27 - Finalização do teste de memória sem apresentar nenhum erro Figura 28 - Medição do uso da memória durante a execução do memtester Figura 29 - Resultado do comando ps em ambiente monoprocessado com o Breve Figura 30 - Resultado do comando ps em cluster com o Breve xi

12 LISTA DE GRÁFICOS Gráfico 1 - Medição de desempenho utilizando Zlib Gráfico 2 - Medição de desempenho utilizando Fibonacci Gráfico 3 - Medição de desempenho utilizando MD5 Gráfico 4 - Medição de desempenho utilizando SHA1 Gráfico 5 - Medição de desempenho utilizando Blowfish Gráfico 6 - Medição de desempenho utilizando Raytracing Gráfico 7 - Medição de tempo de execução do PovRay Gráfico 8 - Instâncias benchmark.pov em cluster Gráfico 9 - Instância benchmark.pov em computador standalone Gráfico 10 - Gráfico da quantidade de pesquisa sobre cluster, grid e cloud no Google xii

13 LISTA DE TABELAS Tabela 1 - Arquivos criados na instalação do Kerrighed Tabela 2 - Valores para a implementação do cluster do laboratório Tabela 3 - Valores para a contratação de serviço de cloud Tabela 4 - Comparação dos custos de implementação do cluster e a contratação de cloud xiii

14 LISTA DE FÓRMULAS Fórmula 1 - Fórmula para escalonamento para sistemas em tempo real periódicos Fórmula 2 - Performance teórica de pico Fórmula 3 - Ganho de velocidade Fórmula 4 - Fórmula de Amdahl Fórmula 5 - Variação da fórmula de Amdahl xiv

15 LISTA DE SIGLAS E ACRÔNIMOS ACM: Association for Computing Machinery API: Application Programming Interface BOINC: Berkeley Open Infrastructure for Network Computing CAPTCHA: Completely Automated Public Turing test to tell Computers and Humans Apart CIFS: Common Internet File System CMG: Computer Measurement Group CRT: Cathode Ray Tube CVSS: Common Vulnerability Scoring System DARPA: Defense Advanced Research Projects Agency DCT: Discrete Cosine Transform DDoS: Distributed Denial of Service DFSA: Direct File System Access DHCP: Dynamic Host Configuration Protocol DoS: Denial of Service DSL: Digital subscriber Line DSM: Distributed Shared Memory EDF: Earliest Deadline First FEPAF: Fundação de Estudos e Pesquisas Agrícolas e Florestais FTP: File Transfer Protocol GPU: Graphics Processing Unit HPC: High-Performance Computing xv

16 HTTP: Hypertext Transfer Protocol IA: Inteligência Artificial IaaS: Infrastructure as a Service IANA: Internet Assigned Numbers Authority IDL: Interface Definition Language IGMP: Internet Group Management Protocol INRIA: Institut National de Recherche en Informatique et en Automatique IPC: Interprocess Communication IS-IS: Intermediate System to Intermediate System ISO/OSI: International Standards Organization/Open Systems Interconnection JFIF: JPEG File Interchange Format JPEG: Joint Photographic Experts Group LUI: Linux Utility for cluster InstalI LVS: Linux Virtual Server MAC: Medium Access Control Mosix: Multicomputer Operating System UnIX MP3: MPEG Layer 3 MPEG: Motion Picture Experts Group MPI: Message Passing Interface MPLS: Multi-protocol Label Switching MPP: Massively Parallel Processing NBX: Nugo Black Box NFS: Network File System xvi

17 NP: Nondeterministic Polynomial Time NSCS: National Supercomputing Centre in Shenzhen NSF: National Science Foundation NTSC: National Television System Committee NUGO: Nutrigenomics Organization OSCAR: Open Source Cluster Application Resources PAL: Phase Alternating Line PBS: Portable Batch System PCM: Pulse Code Modulation PCM: Pulse-Code Modulation PDU: Protocol Data Unit PovRay: Persistence of Vision Ray Tracer PPM: Preempetive Process Migration PVFS: Parallel Virtual File System PVFS: Parallel Virtual File System PVM: Parallel Virtual Machine QoS: Quality of Service RMS: Rate Monotonic Scheduling ROI: Return of Investment RPC: Remote Procedure Call RPM: Red Hat Package Manager RSTP: Real-time Streaming Protocol RSVP: Resource Reservation Protocol xvii

18 RTCP: RTP Control Protocol RTP: Real Time Protocol RTP: Real-time Protocol RTSP: Real Time Streaming Protocol SDSC: San Diego Supercomputer Center SIS: System Installation Suite SLA: Service-Level Agreement SMP: Symmetric Multiprocessing SMT: Simultaneous Multithreading SMTP: Simple Mail Transfer Protocol SONET: Synchronous Digital NETwork SSI: Single System Image TCP-IP: Transport Control Protocol Internet Protocol TMT: Testing and Monitoring Tool UDP: User Datagram Protocol UHN: Unique Home-Node UTP: Unshielded Twisted Pair VLAN: Virtual Local Area Network VNC: Virtual Network Computing VoD: Vídeo on Demand VoIP: Voice over IP WFG: Wait-For-Graph XML: Extensible Markup Language xviii

19 SUMÁRIO FICHA CATALOGRÁFICA... iii AGRADECIMENTOS... vi RESUMO... viii ABSTRACT... ix LISTA DE FIGURAS... x LISTA DE GRÁFICOS... xii LISTA DE TABELAS... xiii LISTA DE FÓRMULAS... xiv LISTA DE SIGLAS E ACRÔNIMOS... xv INTRODUÇÃO METODOLOGIA Capítulo 1 Conceitos teóricos sobre processamento Monoprocessado e Distribuído Características de um Cluster de Computadores Fundamentos dos Sistemas Operacionais Convencionais Dificuldades na manipulação de processos num ambiente monoprocessado Escalonamento de processos ou threads Escalonamento em sistemas em tempo real Fundamentos de Sistemas Operacionais com Processamento Distribuído Redes de Computadores Processos e Threads RPC (Remote Procedure Call) e MPI (Message Passing Interface) Gerenciamento de Memória: Dispositivos de Entrada/Saída: Arquivos: Chamadas de Sistema (System Calls) e Comunicação Interprocessos: Dificuldades na manipulação de processos num ambiente de processamento distribuído Aplicações Multimídia em Sistemas Distribuídos Conclusão do Capítulo Capítulo 2 Apresentação de Cluster em Linux na Modalidade HPC com ênfase em Kerrighed Classificação de Michael J. Flynn (FLYNN, 1972) das arquiteturas de Computadores Tipos de clusters Cluster Beowulf: Cluster OSCAR (Open Source Cluster Application Resources): Projeto Rocks Cluster OpenMosix Cluster Kerrighed Conclusão do Capítulo Capítulo 3 Apresentação do Laboratório Descrição do hardware utilizado Descrição do Sistema Operacional utilizado Descrição da configuração do Cluster Kerrighed implementada

20 Descrição dos aplicativos para testes Conclusão do capítulo Capítulo 4 Medições e análises Performance teórica de pico Performance das Aplicações Performance da rede Abordagem e ferramentas de análise do desempenho do cluster Análise geral dos resultados Medição e análise do throughput real das conexões de rede Estresse do cluster e análise para confirmar a efetiva funcionalidade do mesmo Teste e medição de memória Medição e análise do sistema em cluster e nos nós com ferramentas de benchmark apresentadas no aplicativo hardinfo Medição e análise do sistema em cluster e monoprocessado utilizando um aplicativo de Design Digital (PovRay) Medição e análise do sistema em cluster e monoprocessado utilizando um aplicativo de Inteligência Artificial (Breve) Capítulo 5 Conclusão Viabilidade Econômica do Cluster Kerrighed Viabilidade Técnica do cluster Kerrighed Considerações Finais Capítulo 6 - Um olhar para o presente e um olhar para o futuro da Tecnologia de Cluster Um olhar para o presente Um olhar para o futuro Conclusão do capítulo Referências: GLOSSÁRIO

21 INTRODUÇÃO Antes de adentrar na questão principal do trabalho, faz-se necessário estabelecermos alguns conceitos relacionados ao tema e o método de abordagem do mesmo. Quanto ao tema, é importante salientar que estamos trabalhando no campo da tecnologia, mas precisamos circunscrever o significado de tecnologia em relação aos conceitos de ciência e engenharia, estabelecendo os limites e abrangência de cada uma dessas atividades. Numa visão conceitual podemos estabelecer que ciência é um corpo de conhecimento em determinada área de pesquisa, que procura descrever o mundo físico e suas propriedades através de uma metodologia. A engenharia busca soluções para problemas de natureza mais geral, utilizando o conhecimento gerado pela ciência dados certos recursos e limites. E por fim a tecnologia que é ciência e a engenharia aplicada visando à provisão de soluções para as necessidades humanas pontuais, usualmente utilizando o conhecimento construído pela engenharia, mas em algumas ocasiões, buscando as soluções diretamente do repositório de conhecimento da própria ciência. Usando como exemplo o próprio tema da pesquisa, a ciência descobriu as propriedades dos semicondutores e sua aplicação em circuitos digitais, especialmente na criação de operações de natureza binária e na transmissão de informações em meios elétricos e óticos. A engenharia desenvolve computadores, softwares e equipamentos de comunicação de dados baseados nos conceitos científicos, mas em ambiente de laboratório e não em larga escala. A tecnologia desenvolve produtos para uso geral e em larga escala, baseados no conhecimento e técnicas desenvolvidas pela engenharia, no nosso caso, microcomputadores, sistemas operacionais, softwares e equipamentos de rede. Porém apesar da área de pesquisa em questão ter uma ligação relativamente clara e interdependente entre a ciência, a engenharia e a tecnologia, isso não ocorre de modo geral, segundo Derek de Solla Price (PRICE, 1976). Ele coloca: Em termos gerais, a ciência não tem prestado grande auxílio à tecnologia, embora, uma e outra vez, deparemos com eventos anômalos e traumatizantes, como os transistores e a penicilina. Importa ser cauteloso: trata-se de grandes exceções, não a regra. Realmente existe um hiato muito grande entre essas duas atividades, onde atuam pessoas com perfil intelectual e psicológico muito distinto, também com objetivos e motivações muito diferentes. 21

22 Apesar da consciência de que sou um tecnologista, com as características próprias desse perfil, procurarei nesse trabalho utilizar a metodologia e a visão científica para analisar a pesquisa proposta, pois acredito que uma abordagem científica baseada num trabalho empírico-indutivo, conseguirá obter melhores resultados do que um simples benchmarking 1. Estabelecido os conceitos, podemos seguir em frente com esse prólogo, abordando a agora a questão da metodologia indutiva. Apesar de adepto à experimentação, para Hume (HUME, 1999) a experimentação e em seguida a conclusão obtida através do método indutivo, não seriam adequadas, pois, segundo ele, não pode haver argumentos lógicos válidos que nos permitam afirmar que aqueles casos dos quais não tivemos experiência alguma se assemelham àqueles que já experimentamos anteriormente, consequentemente, mesmo após observar uma associação constante ou frequente de objetos, não temos motivo para inferir algo que se refira a um objeto que não experimentamos. Em outras palavras, Hume não aceitava o método indutivo, pois, não sua visão, essa conclusão será de natureza psicológica, baseada no hábito de acreditar em leis, em assertivas que afirmam a regularidade de certos eventos. 1 Aqueles que já atuam e convivem no meio e em atividades relacionadas à Tecnologia da Informação, sabem das dificuldades encontradas ao se traduzir algumas palavras ou termos em inglês para a Língua Portuguesa, buscando o mesmo sentido que o original. Nesse trabalho iremos traduzir, segundo o nosso juízo, os termos em inglês com maior clareza e acuidade possível, porém apresentaremos a palavra ou o termo em inglês caso percebamos que a tradução não reflete o significado original da palavra em sua plenitude. Palavras que já existem nos principais dicionários da Língua Portuguesa não serão destacadas nesse trabalho. 22

23 Popper (POPPER, 1994) questiona essa posição, mas também tem reservas ao método indutivo e apresenta o que ele chama da teoria das conjecturas e refutações onde estabelece que ao invés de esperar passivamente que as repetições nos imponham suas regularidades e, por conseguinte a indução, nós devemos, segundo ele, de modo ativo impor regularidades ao mundo, tentando identificar similaridades e interpretá-las em termos da teoria que defendemos. Ele também estabelece que as teorias precisam ser testadas através de experimentos, mas não com o intuito de prová-las mas sim de refutá-las. Como Popper coloca Só a falsidade de uma teoria pode ser inferida da evidência empírica, inferência que é puramente dedutiva. Kuhn (KUHN, 1978) na sua teoria da estrutura das revoluções científicas coloca que o princípio de falsificação de Popper é semelhante ao que na sua teoria ele chama de experiências anômalas, isto é, experiências que, ao evocarem crises, preparam o caminho para uma nova teoria. Porém, na visão de Kuhn se todo e qualquer fracasso na tentativa de adaptar teoria e dados fosse motivo para a rejeição de teorias, todas as teorias deveriam ser sempre rejeitadas. Apenas para encerrar essas considerações sobre o método experimental, gostaria de acrescentar apenas a visão de Kant (KANT, 1999), que afirma que, apesar da experiência produzir conhecimento, existe um conhecimento a priori que não é derivado de nenhuma experiência que se contrapõe ao conhecimento empírico ou a posteriori. Diante dessas teorias e ideias, estabelecerei a minha estratégia de pesquisa. É importante ressaltar que minha pesquisa está totalmente no domínio da tecnologia e que alguns conceitos até agora apresentados referem-se mais propriamente à ciência. Apesar disso, considero salutar aplicar essas ideias e considerações a minha pesquisa para que a mesma se torne mais consistente e circunspecta. Assim estarei atento quanto o grau de subjetividade na análise dos testes experimentais mesmo que os mesmos resultados se repitam numa frequência significativa assim como terei critério ao inferir um resultado ou conclusão, procurando fazê-lo se realmente a similaridade dos elementos comparados seja significativa e clara. Também estabelecerei questionamentos que testem a falsidade das minhas proposições, mas dentro de limites para não invalidar de maneira precipitada a teoria como um todo. 23

24 Terei também ciência que iniciarei os trabalhos com um conhecimento a priori impuro, pois é fruto de certo empirismo obtido na minha experiência técnica. Estabelecidas as diretrizes metodológicas da pesquisa, podemos introduzir o tema de minha pesquisa, que é verificar empiricamente se um sistema de cluster de computadores com o sistema operacional Linux seria uma infraestrutura viável para aplicações de Design Digital e Inteligência Artificial. Sem dúvida que sistemas de cluster já são largamente usados tanto nas instituições acadêmicas com nas corporações, por exemplo, se acessarmos hoje o site que estabelece um ranking de computadores mais poderosos do mundo, segundo seus critérios, temos um cluster na quarta posição com processadores instalado no NSCS (National Supercomputing Centre in Shenzhen) na China. Assim esse não é o foco da pesquisa, a viabilidade dos sistemas de cluster de modo geral, mas verificar de maneira metódica o comportamento do mesmo ao executar aplicações especialistas de Design Digital e Inteligência Artificial com todas suas particularidades e características semelhantes em relação a aplicações de outra natureza. A história de cluster de computadores se confunde com a história das próprias redes, pois apenas através de redes de comunicação que foi possível computadores independentes trabalharem de maneira paralela como uma única entidade. Os primeiros clusters comerciais foram o ARCnet desenvolvido pela Datapoint em 1977 e o VAX cluster desenvolvido pela DEC em Outros clusters que tiveram alguma notoriedade foram o Tandem Himalaya por volta de 1994 e o IBM S/390 Parallel Sysplex também no mesmo período. 24

25 Com o surgimento da PVM (Parallel Virtual Machine) a construção de cluster tornou-se mais acessível por ser uma arquitetura aberta (open source) baseada em TCP-IP, podendo assim compor cluster com computadores heterogêneos totalmente transparentes para o usuário final. Após esse sucinto histórico da tecnologia, podemos apresentar como esse trabalho será estruturado. No capítulo 1, apresentaremos os conceitos de sistemas distribuídos tendo como contraponto os sistemas monoprocessados. No capítulo 2, abordaremos os principais modelos de cluster em sistemas operacionais Linux, esmiuçando o que será o foco do nosso estudo que é Kerrighed. No capítulo 3, apresentaremos o nosso laboratório com uma descrição detalhada de cada item do mesmo, assim como as configurações aplicadas aos computadores. Apresentaremos também as aplicações que serão executadas nesse sistema e suas características básicas no que concerne ao modo de processamento e alocação de recursos. No capítulo 4, descreveremos os testes de execução das aplicações previamente escolhidas e a devida medição, que envolverá em linhas gerais, utilização de CPU, de memória, de banda nas conexões de rede, tempo de resposta, a carga em cada nó do cluster, etc. Após a execução e medição dos programas, analisaremos os resultados tendo como referência um computador com as mesmas características dos nós que compõe o cluster, executando as mesmas aplicações. No quinto capítulo, a partir da análise realizada no capítulo anterior, chegaremos à conclusão ou pelo menos em indicações sobre a viabilidade do uso do sistema Kerrighed na execução de sistemas de Design Digital e Inteligência Artificial que foram executados em laboratório, utilizando como contraponto tecnologias alternativas de computação massiva como computação em grid e computação em cloud. No sexto e último capítulo será apresentado como um anexo, casos que representarão o estado da arte em tecnologia de cluster com um olhar para o presente e um olhar para o futuro. A fundamentação teórica desse trabalho visa ajudar aos pesquisadores e profissionais que não atuam com infraestrutura, subsídios para entender as especificidades técnicas dessa matéria, como suporte para a realização de suas atividades, como por exemplo, o desenvolvimento de códigos para Design Digital e Inteligência Artificial. Apesar do foco desse trabalho sejam aplicações de Design Digital e Inteligência Artificial, as constatações e conclusões apresentadas nesse trabalho poderão ser aplicadas em outras áreas da Tecnologia da Informação. 25

26 Uma proposição inicial seria que o sistema de cluster aumentaria a capacidade de processamento linearmente, isto é, na mesma medida em que adicionamos computadores ao cluster, aumentaríamos linearmente o desempenho do mesmo, a ponto de considerarmos um cluster de servidores Linux uma infraestrutura viável para implementação de aplicações de Inteligência Artificial e Design Digital. Porém sabemos que essa proposição não corresponde à realidade, assim consideraremos a agregação de 80% da capacidade computacional a cada novo nó inserido ao cluster, prevendo alguma perda devido à latência da rede, dificuldade das aplicações realizarem processamento paralelo, gerenciamento de memória em ambientes distribuídos e os próprios recursos computacionais para as funcionalidades do cluster. Iremos testar essa hipótese com a realização desse laboratório. Inicialmente adotamos o projeto OpenMosix como sistema de cluster a ser utilizado no laboratório idealizado para esse trabalho, porém o projeto foi encerrado em março de 2008 pelo professor Moshe Bar. Iniciamos os trabalhos de implementação do projeto em laboratório e ao consultar um dos autores mais proeminentes no Brasil em cluster em Linux, Marcos Pitanga, fomos aconselhados a trabalhar com o cluster Kerrighed que também é SSI (Single System Image), sendo um projeto em franca atividade de implementação e aperfeiçoamento. Assim ao iniciarmos os trabalhos de laboratório, optamos por utilizar pelo cluster em Linux Kerrighed. Objetivo final desse trabalho é verificar se uma plataforma de baixo custo de hardware, utilizando software aberto é viável técnica e financeiramente para a execução de aplicações HPC com ênfase em Inteligência Artificial e Design Digital. 26

27 METODOLOGIA Trabalho baseado em uma abordagem empírica indutiva, buscando através de um laboratório que consiste de um cluster Linux e aplicações com ênfase em Inteligência Artificial e Design Digital, analisar a viabilidade da utilização de cluster SSI em ambientes de pequeno e médio porte que poderá apresentar-se como uma opção viável em termos técnicos e financeiros para alojar esses tipos de aplicações. 27

28 Capítulo 1 Conceitos teóricos sobre processamento Monoprocessado e Distribuído Considerações iniciais do capítulo Além de apresentar as características básicas de um sistema em cluster, esse capítulo tem como objetivo apresentar os componentes, tecnologias e desafios intrínsecos da computação monoprocessada e distribuída, apontando diferenças, semelhanças e relações. Acreditamos que essa fundamentação teórica será de grande valia ao estudarmos o foco desse trabalho em termos de solução, que seria o sistema em cluster Kerrighed, que apesar de possuir técnicas próprias para algumas das disciplinas da teoria da computação, como por exemplo, a alocação e o mapeamento de memória, as teorias convencionais sempre no servirão de base para o entendimento de novas abordagens seja por semelhança seja por contraponto. Características de um Cluster de Computadores Tanenbaum 2 (TANENBAUM, 1995) coloca que um sistema distribuído é uma coleção de computadores independentes que parecem aos usuários do sistema como um só computador. Existem alguns autores como Gregory F. Pfister 3 que fazem distinção entre sistemas distribuídos e clusters, mas nesse trabalho não faremos essa diferenciação, pois além do tema ser controverso, em se tratando de cluster de alto desempenho, essa distinção não se aplica a nossa abordagem do assunto. 2 Andrew Stuart Tanenbaum é o chefe do Departamento de sistemas de computação, na Universidade Vrije, Amsterdã nos Países Baixos. Ele é o autor do Minix, um sistema operacional baseado no Unix com propósito educacional, e bastante conhecido por seus livros sobre ciência da computação. Nasceu na cidade de Nova Iorque e cresceu em White Plains no estado de Nova Iorque. Recebeu o título de bacharelado pelo MIT e o doutorado pela UC Berkeley em Atualmente ministra aulas sobre Organização de Computadores e Sistemas Operacionais. 3 Gregory Y. Pfister obteve seu doutorado no MIT. Tendo sido instrutor nessa instituição, assim como professor assistente na Universidade da California, Berkeley. Por muitos anos, ele foi membro da equipe de Pesquisa e Desenvolvimento da IBM num nível sênior. Ele detém inúmeras patentes em processamento distribuído. Autor do livro In Search of Clusters. 28

29 Apenas título de registro Pfister (PFISTER, 1998) afirma que clusters são geralmente grupos de computadores homogêneos em menor escala, dedicados a um número pequeno e bem definido de tarefas, nas quais o cluster atua como uma única máquina, porém os clusters atualmente podem ser compostos de máquinas heterogêneas e de um número grande de computadores, assim a definição de Pfister não se aplica ao nosso estudo e concepção de um cluster. Tanenbaum (TANENBAUM, 1995) identifica características essenciais no desenvolvimento de sistemas distribuídos que são: Transparência Flexibilidade Confiabilidade Desempenho Escalabilidade Transparência Transparência é capacidade do sistema em dar a impressão ao usuário de que ele está acessando apenas um computador convencional, quando na realidade há um cluster de computadores realizando as tarefas. A transparência pode ser vista sob os seguintes aspectos: Transparência de localização: Os usuários não podem dizer onde os recursos estão localizados. Transparência de migração: Os recursos podem se mover a qualquer momento sem mudarem seus nomes. Transparência de replicação: Os usuários não podem dizer quantas cópias dos recursos existem. Transparência de concorrência: Os usuários podem compartilhar os recursos automaticamente. Transparência de paralelismo: As atividades ocorrem paralelamente sem os usuários o saberem. 29

30 Flexibilidade Podemos dizer que temos duas vertentes para o desenvolvimento de estruturas de sistemas operacionais distribuídos. Temos os sistemas operacionais com o kernel monolítico e temos os sistemas operacionais com microkernel. O primeiro possuindo a maioria dos serviços em si mesmo, tendo controle sobre sistemas de arquivos, conexão com a rede, etc. e o segundo realizando o mínimo de operações possíveis deixando que as outras tarefas necessárias para a obtenção dos resultados desejados, sejam realizadas fora do kernel, em nível de usuário do sistema. Diferentemente dos sistemas monolíticos, o microkernel não provê um sistema de arquivo ou diretórios, gerenciamento completo dos processos ou um manuseio considerável de chamadas de sistema. Dessa maneira, os sistemas com microkernel são essencialmente mais flexíveis, proporcionando um desenvolvimento modular de funções e serviços, podendo os mesmos estar fisicamente em recursos computacionais diferentes. Além disso, esse tipo de sistema torna a inclusão e manutenção dos serviços muito mais simples, pois não requer que o sistema seja parado para que se habilite um novo kernel com um novo serviço. A vantagem de um kernel monolítico é o desempenho, pois todas as instruções serão realizadas na velocidade do barramento interno do computador, não necessitando de utilizar uma estrutura de rede para essa atividade. O microkernel, na visão de Tanenbaum (TANENBAUM, 1995), seria a abordagem mais adequada para o desenvolvimento de sistemas distribuídos. Segue algumas funções básicas realizadas por sistemas microkernel: Mecanismo de comunicação interprocessos; Algum gerenciamento de memória; Pequena quantidade processos de baixo nível responsáveis por gerenciamento e scheduling; Entrada/Saída em baixo nível; 30

31 Confiabilidade Um dos primeiros objetivos de se construir sistemas distribuídos foi de fazê-los mais confiáveis que os sistemas monoprocessados. A ideia seria que se um computador ficasse fora de funcionamento, outro assumiria seu trabalho. Na teoria, a confiabilidade de um sistema distribuído seria uma operação lógica OU das confiabilidades das máquinas que o compõe. Por exemplo, se tivermos três servidores de arquivos com 0,95 de chance de estarem indisponíveis, a probabilidade dos três computadores estarem indisponíveis ao mesmo tempo seria de (1-0,05 3 ) = 0,999875, muito melhor do que qualquer servidor individual. Na prática a função lógica E estaria mais próxima da realidade do que a operação OU, porque manter num sistema distribuído todos os processos, arquivos, usuários exatamente iguais em todos os computadores que o compõe, é uma tarefa árdua em termos técnicos e financeiros, aspectos como disponibilidade, segurança, consistência e tolerância a falhas são desafios para os desenvolvedores de sistemas distribuídos. Em geral os sistemas distribuídos trabalham de modo a esconder do usuário do sistema que algum dos seus componentes não está disponível em dado momento. Desempenho No tema de sistemas distribuídos sempre teremos como pano de fundo o desempenho. Sempre buscaremos a condição de uma aplicação ser executada mais rapidamente num sistema distribuído do que num único servidor com capacidade computacional de um dos componentes desse cluster. Infelizmente, na prática a obtenção desse objetivo não é tão fácil de ser alcançada. A primeira questão é que na medição do desempenho (benchmarking), pode-se utilizar várias métricas como tempo de resposta, vazão (número de Jobs por hora), utilização do sistema (recursos computacionais) e consumo da capacidade da rede. A consolidação dessas métricas nem sempre é uma atividade fácil de ser realizada assim como as conclusões derivadas dessa consolidação. O tipo de operação escolhida também influencia em muitos nos resultados de um benchmarking, por exemplo, trabalhar com um experimento computacional que envolve um número grande de atividades de alto consumo de CPU terá um resultado muito diverso que trabalhar analisando um arquivo de grandes proporções buscando algum padrão. 31

32 A infraestrutura de rede sempre será um elemento crítico num sistema distribuído. Uma comunicação entre duas máquinas na melhor das condições leva pelo menos um milissegundo, que comparado à taxa de transferência interna de um processador ou mesmo de um barramento de um computador, pode ser considerado um tempo extremamente longo, mesmo em conexões de LAN de 10 Gibabits. Quando falamos em desempenho em processamento distribuído temos que pensar na granularidade computacional. Utilizar um recurso computacional remoto de modo reduzido, como por exemplo, realizar uma operação lógica simples entre dois números, não será usualmente interessante em termos de desempenho num ambiente distribuído, devido ao overhead da comunicação de dados, por outro lado, se realizarmos uma tarefa que exija um longo processamento computacional para uma mesma massa de dados, usualmente é um trabalho adequado para um processamento distribuído. Assim quando processos realizam poucas instruções e precisam comunicar-se muito, dizemos que são muitos granulares, quando realizam muitas instruções com pouca troca de informação, dizemos que são poucos granulares. Naturalmente num ambiente de processamento distribuído uma menor granularidade computacional, significa usualmente um melhor desempenho. Escalabilidade Falando em cluster em Linux temos na plataforma Beowulf no projeto Goddard Casse Flight Center, um cluster com 199 servidores e na Caltech um sistema com 140 nós de cluster. Um dos clusters da Yahoo (Apache Hadoop Cluster) tem 910 nós, porém esse é um sistema de cluster apenas para executar as funcionalidades de um servidor web num modelo de grid, que é um agrupamento de computadores visando um aumento de capacidade de processamento que estão geograficamente separados, porém podendo ou não estar disponíveis, para a realização de uma determinada tarefa computacional. O grande desafio da escalabilidade não seria a quantidade de nós que poderiam ser agregados a um cluster e sim o desenvolvimento de sistemas operacionais e aplicações que usufruam devidamente desse tipo de configuração. Dessa maneira modelos convencionais de processamento centralizado não são adequados, em muitas situações, para serem executados num sistema em cluster. 32

33 Seguem algumas características de sistemas adequados para trabalhar num cluster: Nenhuma máquina tem uma completa informação sobre o estado de todo o sistema. As máquinas tomam as decisões baseadas na informação local. A falha numa máquina não afeta o funcionamento do sistema. Não existe uma premissa implícita que exista um sistema global de sincronismo (clock). Sobre o último tópico, estamos considerando o uso de cluster para fins gerais e não para sistemas multimídia distribuídos que necessitam de um sincronismo adequado para operarem satisfatoriamente. A escalabilidade só faz sentido quando as aplicações são compatíveis com um modelo de cluster de computadores. No nosso trabalho, em especial, buscaremos aplicações de inteligência e Design Digital que satisfaçam esses requisitos. Apesar dessas restrições, os sistemas de cluster são técnica e financeiramente viáveis para uma grande quantidade de aplicações. Fundamentos dos Sistemas Operacionais Convencionais Para que possamos melhor compreender os princípios utilizados no processamento distribuído precisamos conhecer alguns componentes do processamento tradicional, isto é, computadores monoprocessados. O objetivo dessa apresentação é apenas discorrer sobre os componentes e entidades do processamento convencional que necessitam ser adequadas ou pelo menos consideradas quando atuando com sistemas de processamento distribuído ou clusters. Serão abordados também os desafios que tecnologia enfrenta, de certa forma, inerentes aos próprios princípios que regem a computação convencional contemporânea que em regra geral tornam-se mais críticos e de mais difícil solução ou mitigação quando tratados no domínio da computação distribuída. 33

34 Processos: Todo software executável num computador, algumas vezes incluindo o próprio sistema operacional, é organizado num número de processos sequenciais. Um processo é um programa executável, com determinados valores nos contadores, registros e variáveis. Mesmo num sistema monoprocessado, temos a impressão de que os processos são executados paralelamente, mas na realidade eles compartilham uso da CPU em intervalos muito rápidos que nos dão essa impressão de um pseudo-paralelismo. É importante ressaltar que em sistemas monoprocessados não podemos precisar exatamente quanto tempo um processo durará, caso seja executado mais de uma vez, pois não saberemos quanto tempo ele terá para fazer uso da CPU em cada execução. Essa falta uniformidade se acentua quando tratamos de sistemas distribuídos, questão iremos tratar no transcorrer desse trabalho. Existem trabalhos recentes onde se trabalha com mecanismos de scheduler mesmo em ambientes monoprocessados, para que se tenha um maior controle do tempo de execução de cada processo. Podemos citar o trabalho de Silviu S. Craciunas, Christoph M. Kirsch e Harald Röck 4, que trabalha com scheduler de chamadas de sistema para alcançar essa uniformidade e melhor desempenho, baseando-se no princípio de Traffic Shaping utilizado em roteadores. Um processo sempre tem um espaço de memória (address space) onde ele armazena as informações que está manipulando que podem ser um programa executável, dados de um programa ou a própria pilha do processo. Também um processo sempre tem alguns registradores associados ao mesmo, que podem ser contadores, ponteiros de pilhas, registradores de hardware, etc. Usualmente um processo é inicializado através de uma chamada de sistema (system call) que é constituída de diretivas que são linhas de programação em C, se estamos falando em sistemas Unix e Linux, desenvolvidos para interagir com o sistema operacional e com a linguagem de máquina (Assembler), para realizar funções de baixo nível e de interação com o próprio sistema operacional. 4 Autores do artigo I/O Resource Management through System Call Scheduling pela Universidade de Salzburg, Austria dentre outros trabalhos. 34

35 Quando um processo faz uma chamada para a execução de outro processo, dizemos que o primeiro é um processo pai do segundo, daí a necessidade de comunicação interprocessos, que num ambiente monoprocessado que é consideravelmente mais simples do que em sistemas distribuídos. Threads Embora tenham algumas semelhanças. Processos e threads são entidades distintas com aplicações distintas. Os processos têm como função principal agrupar recursos e executar operações com eles. Em algumas situações é interessante separar o agrupamento dos recursos do processamento dos mesmos. Nesse cenário que temos as threads. Elas apenas executam operações, possuindo um contador para ter um controle da execução, um registrador que armazena as variáveis de trabalho e uma pilha que contém um histórico da execução. As threads acrescem aos processos a capacidade de realizar múltiplas execuções num mesmo ambiente de processo, com um alto grau de independência. Tendo múltiplas threads sendo executadas num mesmo processo seria semelhante a ter múltiplos processos sendo executados num mesmo computador. As primeiras compartilham espaço de endereçamento, arquivos abertos, etc. Os últimos compartilham memória física, discos, impressoras, etc. Quando temos um cenário de multi-thread, isto é, múltiplas threads associadas a um único processo, temos também a impressão de um paralelismo, porém como os processos, na computação convencional, cada thread é executada por vez. Assim se tivermos três threads sendo executadas sequencialmente por um processador, cada uma terá apenas um terço da capacidade do mesmo. Um motivo para utilizarmos threads seria aplicações que necessitem de processos paralelos. Como as threads compartilham o mesmo espaço de memória e os próprios dados, elas são ideais para aplicações que necessitam dessa característica, como, por exemplo, um servidor de arquivos numa rede local. Outra vantagem das threads é que como elas não possuem nenhum recurso associado às mesmas, elas são criadas e finalizadas mais facilmente. Finalmente elas têm uma maior performance e também são mais apropriadas para ambientes multi-processados onde teremos um paralelismo real. 35

36 Gerenciamento de Memória: Todo sistema operacional precisa de uma memória principal onde os programas que estão sendo executados possam ser alojados. Em sistemas operacionais mais simples somente um programa por vez pode fazer usado no espaço de memória. Nos sistemas mais sofisticados a memória pode ser compartilhada por mais de um programa, através da utilização do conceito de endereçamento de memória. Usualmente um processo tem um conjunto de endereços de memória com os quais ele pode trabalhar. Esse endereço pode ser de 32 ou 64 bits que significa respectivamente 232 e 264 bytes de tamanho de memória por endereço. Outro mecanismo para aumentar a quantidade de memória disponível para os processos é a memória virtual ou paginação que é a gravação temporária dos dados da memória no disco rígido do computador, liberando a memória real para outras funções dos processos. Dispositivos de Entrada/Saída: Todo o computador tem dispositivos de E/S (Entrada/Saída), como teclado, impressoras, monitores, etc. O sistema precisa gerenciar esses dispositivos na medida em que os processos e os programas solicitem uso de algum deles. Num sistema de cluster, também esses recursos também precisarão receber as requisições para o seu uso como que partissem de um único computador. Arquivos: Todo o sistema operacional possui um sistema de arquivos. Uma das principais funções de um sistema operacional é realizar uma abstração dos aspectos complexos do funcionamento real de um computador apresentando ao usuário ou mesmo programador uma interface amigável. Assim é com o sistema de arquivos. Os sistemas de arquivos são hierárquicos e também possuem o conceito de diretórios que é um agrupamento de arquivos. 36

37 Todo arquivo num sistema de arquivos possui um caminho (path) que é uma lista de todos os diretórios que necessita ser informada para acessar determinado arquivo. Todo processo tem um diretório de trabalho que pode ser alterado através de uma chamada de sistema. Novamente, o gerenciamento de um sistema arquivos num ambiente monoprocessado, apesar de ter certa complexidade não se compara às dificuldades em manter-se um sistema de arquivo num sistema de cluster, garantindo uma uniformidade e coerência nos arquivos que estão espalhados entre os nós que compõe o mesmo. Chamadas de Sistema (System Call): A interface entre o sistema operacional e os programas dos usuários é definida por um grupo de chamadas de sistemas previamente definidas. Apesar da maioria das chamadas de sistema ser altamente dependente das características do computador e usualmente escrita em linguagem de máquina (assembler), o desenvolvimento das mesmas foi simplificado através da criação de bibliotecas de procedimentos (procedures libraries) que facilitam esse trabalho por se poder utilizar linguagens de programação mais acessíveis como a C. De forma simplificada podemos descrever os passos da execução de uma chamada de sistema como segue: A chamada de sistema pertencente à biblioteca de procedimentos é chamada. O programa que iniciou a chamada de sistema coloca os parâmetros fornecidos na respectiva pilha. A chamada de sistema é executada com os parâmetros fornecidos. A biblioteca de procedimentos a qual pertence à chamada de sistema, que é usualmente escrita em linguagem de máquina, coloca o número da chamada de sistema num registrador conforme estabelecido pelo sistema operacional. 37

38 Ocorre então uma instrução conhecida como TRAP, que é a mudança do modo usuário para o modo kernel (núcleo do Sistema Operacional) que inicia a execução da chamada de sistema. O kernel verifica o número da chamada de sistema e o envia para o devido manipulador de chamadas de sistema (system call handler). O manipulador de chamadas de sistema é executado. Após isso o sistema retorna para o modo usuário via instrução TRAP. O programa que executou a chamada de sistema limpa a pilha utilizada para colher os parâmetros da mesma, procedimento usual nesse tipo de manipulação. A quantidade de chamadas de sistema varia entre os sistemas operacionais. O Linux kernel 2.6, por exemplo, tem 271 chamadas de sistema. Dentre os vários serviços realizados pelas chamadas de sistema temos como os mais relevantes o gerenciamento de processos, de arquivos e de sistema de arquivos e diretórios. Muitas das chamadas de sistemas em monoprocessamento podem ser usadas em processamento distribuído através de Remote Procedure Call (RPC). Os parâmetros das chamadas de sistema ao invés de serem colocados num registrador, são colocados numa mensagem e o kernel envia a mensagem para a máquina que deseja que execute a chamada de sistema que retorna o resultado através de outra mensagem para o computador que requisitou a execução remota, que do ponto de vista de RPC seria o client stub no processo e o executante o server stub. Existem outras abordagens para execução de chamadas de sistemas remotamente, como o Kerrighed que realiza a execução remota de chamadas de sistema através da migração de processos entre os nós que compõe um cluster. 38

39 Seguem agora alguns desafios que os desenvolvedores de sistemas operacionais enfrentam na implementação de processos e threads, considerando modelo computacional de Von Neumann 5. IPC (Interprocess Communication) Um componente muito crítico seja na computação tradicional seja na computação distribuída, é a comunicação entre processos. Um exemplo típico de comunicação entre processos é o comando pipeline no ambiente Unix, onde a saída de um processo alimenta a entrada do outro. Existem muitas linhas de programação seja em linguagem de máquina seja em linguagem de alto nível para realizar esse comando que a primeira vista parece simples. Segue um exemplo de um código que escuta a função pipe. A função fork é usada para criar um processo pai e um processo filho. #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h> int main() { char token[100]; FILE *fout; int p[2]; int pid; 5 John Von Neumann, nascido em Budapeste, 28 de dezembro de 1903 foi um matemático húngaro de etnia judaica, naturalizado americano. Contribuiu na teoria dos conjuntos, análise funcional, teoria ergódica, mecânica quântica, ciência da computação, economia, teoria dos jogos, análise numérica, hidrodinâmica das explosões, estatística e muitas outras as áreas da Matemática. De fato é considerado um dos mais importantes matemáticos do século XX. Foi professor na Universidade de Princeton e um dos construtores do ENIAC. 39

40 pipe( p ); /* pipe entre o pai e o filho */ if((pid = fork()) == 0) {/* executa o processo filho P1 */ close(p[1]); /* Fecha o fd (file descriptor) no final de escrita do pipe */ if(dup2(p[0], 0 ) == -1 ) /* Utiliza o stdin para ler o final do pipe */ { perror( "dup2 failed" ); _exit(1); } close(p[0]); /* fecha o fd de final de leitura do pipe */ execl("pipe_newb","pipe_newb","child", 0); /* executa 'Pipe_newB' */ perror("execl Pipe_newB failed"); _exit(1); } else if(pid < 0) {/* fork() failed */ perror("fork CHILD failed"); exit(1); } /* parent executes */ close(p[0]); /* fecha o fd de final de leitura do pipe */ 40

41 /* usa o fdopen() para associar o fluxo de escrita ao final de escrita do pipe entre o pai e filho */ if( ( fout = fdopen( p[1], "w" ) ) == 0 ) { perror( "fdopen failed" ); exit(1); } printf( "Please input a string:\n" ); while( scanf( "%s", token )!= EOF ) { if( fprintf( fout, "%s-parent\n", token ) == EOF ) { perror( "fprintf failed" ); exit(1); } fflush( fout ); } close(1); /* fecha a referência do pipe para enviar o EOF (End of File) */ wait(null); return(0); } 41

42 Vemos que o desenvolvimento de um código para prover uma comunicação entre processo não é trivial e envolve uma lógica considerável na comunicação em si, assim como na prevenção de problemas inerentes a esse tipo de operação, como, por exemplo, ao realizar a comunicação, um processo não poder interferir na execução do outro, necessitando assim que os processos sejam executados e troquem mensagens corretamente de modo a evitar conflitos na utilização dos recursos computacionais. O propósito desse trabalho não será entrar nos detalhes de programação, mas apenas para fins de exposição do princípio, vamos analisar de maneira não aprofundada o código acima. Temos a diretiva include que é usada para executar códigos de programa previamente desenvolvidos, que são tratados pelo pré-processador antes da execução do programa propriamente dito. Nesse caso temos, por exemplo, o código stdio.h que é responsável por gerenciar os dispositivos padrões de entrada/saída. Essas diretivas também são chamadas de bibliotecas da linguagem C. Dessas bibliotecas retiramos os comandos executados nos códigos C. Após as bibliotecas haverem sido carregadas em memória, algumas variáveis são definidas, que para efeito de explanação do código, nos ateremos apenas nas variáveis p que seria de processo e pid que seriam o identificador de processo. A chamada de sistema pipe cria um tubo (pipe) entre um processo pai e um processo filho. Basicamente realizar a função pipe seria usar a saída de padrão de um processo como entrada para outro. O processo filho tem o processo número 1 que é associado a um arquivo Pipe_newB. É importante ressaltar o papel da função dup2, que além de fazer uma duplicação do processo filho original garante que o programa terá o uso da CPU sem interrupção, pela solicitação do kernel por algum outro processo, assim dizemos que esse processo torna-se atômico porque até o mesmo ser finalizado, o sistema como um todo não visualiza a alteração que está sendo realizada. Caso o processo falhe na sua execução o sistema retorna a sua condição original. Retornando a função pipe, em resumo, a saída da entrada padrão (teclado) executado pelo programa pai é escrita na entrada padrão do processo filho (fd file descriptor) no arquivo Pipe_newB. 42

43 O ponto mais importante na elucidação desse exemplo de comunicação interprocessos é conhecermos uma forma básica de processos comunicarem-se, trocando parâmetros e dados, assim como mostrar através de uma função, o tratamento da questão de um processo interferir na execução de outro, podendo gerar uma condição conhecida como race condition que veremos com mais detalhes à frente. É importante ressaltar que todas essas questões levantadas sobre a comunicação entre processos podem ser aplicadas também às threads. Dificuldades na manipulação de processos num ambiente monoprocessado Mesmo no processamento convencional, existem desafios no desenvolvimento ou aperfeiçoamento de sistemas operacionais, no gerenciamento dos recursos da CPU, memória, dispositivos de E/S em face aos vários processos que solicitam o uso dos mesmos, dando a impressão ao usuário que esses processos estão sendo executados paralelamente. Iremos abordar os principais problemas que são inerentes ao modelo computacional corrente e vivenciados na maioria das aplicações. O objetivo é conhecer essas dificuldades na computação monoprocessada que usualmente são acentuadas num ambiente de processamento distribuído. Vale a observação que estamos nos abstraindo nessa abordagem dos processadores que possuem dois núcleos (Dual-Core) ou mesmo os computadores multi-processados (com mais de um processador em seu barramento), pois essas tecnologias não são foco principal dessa análise. Race Condition Race Condition é quando dois ou mais processos estão lendo ou escrevendo em algum dado compartilhado e que o resultado vai depender do momento em que cada processo é executado, podendo um sobrescrever a ação do outro, causando resultados inesperados e incorretos. A maneira óbvia de se evitar essa distorção seria aplicar uma política de mútua exclusão no acesso aos recursos. 43

44 A implementação de regiões ou seções críticas para cada processo e a premissa que dois ou mais processos não podem acessar essas regiões críticas ao mesmo tempo, ajudaria na minimização do problema de race condition, mas não o evitaria para todas as situações. Para podermos ter processos paralelos compartilhando os mesmos recursos de uma forma mais produtiva sem a race condition, sugere-se quatro condições: Dois processos não podem estar ao mesmo tempo em suas regiões críticas. A não existência de premissas sobre velocidade ou número de CPU s. Nenhum processo sendo executado fora da sua região crítica pode bloquear outros. Nenhum processo pode esperar indefinidamente para entrar em sua região crítica. Deadlocks Deadlock é um problema clássico na teoria e na prática da computação. O deadlock é também um problema inerente ao modelo de computação convencional relacionado à alocação de recursos por um sistema operacional. Um deadlock ocorre quando num mesmo instante dois processos tentam acessar um recurso tanto de hardware como de software que está sendo alocado pelo outro. Por exemplo, se num banco de dados onde o processo um acessa o registro um e o processo dois acessa o registro dois e no próximo instante o processo um tenta acessar o registro dois e o processo dois tenta acessar o registro um, nesse momento os processos são bloqueados e ficarão nesse estado indefinidamente. Esse evento é conhecido como deadlock. Coffman 6 deadlock: (COFFMAN, 1971) estabelece quatro condições para que ocorra um Condição de exclusão mútua. Cada recurso, ou está correntemente designado exatamente para um dado processo, ou está disponível. 6 Eduard Grady Coffman é professor de Ciência da Computação na Universidade de Columbia. Em 1994 ele foi nomeado membro da Association for Computing Machinery (ACM). 44

45 Condição de manutenção e espera. Processos que estão correntemente mantendo recursos anteriormente concedidos podem requisitar novos recursos. A falta de percepção de prioridade. Recursos previamente concedidos não podem ser forçosamente tirados de um processo. Eles precisam ser explicitamente liberados pelo o processo que os mantém. Condição de espera circular. Deve haver uma corrente circular de dois ou mais processos, cada um esperando por um recurso mantido pelo próximo membro da corrente. Conseguiremos evitar o deadlock quando conseguirmos fazer com que uma dessas quatro condições não seja satisfeita. Existem várias técnicas e abordagens para a mitigação de deadlocks que não são foco do nosso trabalho, mas basta dizer que elas passam por uma política de alocação de recurso criteriosa assim como uma composição de técnicas de detecção, anulação e prevenção e aplicação de soluções práticas com esse tipo abordagem, que evitariam, de modo eficiente, os deadlocks. (HOWARD JR. 7, 1972). 7 John Hayes Howard Jr. é autor do artigo Mixed solutions for the deadlock problem pela Universidade do Texas, Austin. 45

46 Problema do Jantar dos Filósofos Dijkstra 8 (DIJKSTRA, 1971) elaborou um problema e concebeu uma solução para situações passíveis de se ocorrer no acesso aos recursos pelos processos. A ilustração é bem simples. Temos cinco filósofos numa mesa de jantar com cinco pratos de espaguete e cinco garfos, porém o espaguete é muito escorregadio, sendo necessários dois garfos para poderem comê-lo. À primeira vista, a solução do problema seria simples, teríamos que ter apenas um algoritmo que testasse quando os dois garfos estivessem disponíveis, assim o filósofo poderia utilizá-los. Infelizmente a solução não é tão simples assim. Imaginem se os cinco filósofos ao mesmo tempo verificassem que os garfos estão disponíveis e consequentemente tentam utilizá-los. Eles não terão os dois garfos disponíveis para si e os processos entrarão em deadlock. Podemos aprimorar essa solução não exitosa colocando a premissa de que ao pegar o garfo ao lado esquerdo do prato, o filósofo verifica se o garfo ao lado direito está disponível, caso negativo, ele devolve o garfo do lado esquerdo à mesa. Essa parece ser uma boa abordagem para o problema, mas imagine se os cinco filósofos resolvam ao mesmo tempo pegar o garfo a sua esquerda e testar se o garfo a sua direita está disponível. Eles irão constatar que o garfo a sua direita não está disponível e devolverão à mesa o garfo a sua esquerda. Essa situação continuará indefinidamente, entrando os processos numa condição conhecida como starvation quando os programas são executados continuamente, sem, porém, conseguir realizar qualquer progresso efetivo no andamento dos mesmos, em suma, o programa simplesmente não é executado. Uma ideia seria os filósofos (processos) esperando um tempo aleatório para pegar o garfo a sua esquerda, como é feito em redes locais. Antes de pegar qualquer garfo, o filósofo entraria numa condição de down num semáforo mutex (exclusão mútua), assim nenhum outro filósofo (processo) tentaria pegar qualquer garfo até que o primeiro colocasse os garfos de volta à mesa e entrasse num estado de up liberando assim os recursos (garfos) para os outros processos (filósofos). 8 Edsger Wybe Dijkstra é um cientista neerlandês em computação. Ele recebeu em 1972 o Turing Award por contribuições fundamentais para o desenvolvimento de linguagens de programação, detendo a Schlumberger Centennial Chair em Ciências da Computação na Universidade do Texas de 1984 a

47 Essa solução previne efetivamente os deadlocks e starvation, porém não é eficaz, pois considerando os recursos (pratos e garfos), dois filósofos poderiam comer ao mesmo tempo e nesse caso apenas um comeria por vez. Uma solução mais eficaz para o problema do Jantar dos Filósofos seria utilizarmos um array que controla os estados dos filósofos que seriam: comendo, pensando ou com fome (tentando pegar os dois garfos). Um filósofo só poderia pegar os garfos se nenhum de seus vizinhos estiver comendo. Essa solução contempla um array de semáforos para cada filósofo. São definidas macros para identificar os vizinhos de cada filósofo. Por exemplo, se o processo do filósofo é o dois, seu vizinho da direita seria 1 e o da esquerda 3. Segue um código que aplica a solução para o problema do Jantar dos Filósofos: #define N 5 /* número de filósofos */ #define LEFT (i+n 1)%N /* número de i's à esquerda do vizinho */ #define RIGHT (i+1)%n /* número de i's à direita do vizinho */ #define THINKING 0 /* filósofo está pensando */ #define HUNGRY 1 /* filósofo está tentando pegar os garfos */ #define EATING 2 /* filósofo está comendo */ typedef int semaphore; /* os semáforos são tipos de especiais de int */ int state[n]; /* array para verificar o estado de todos os filósofos */ semaphore mutex = 1; /* mutual exclusão para região críticas */ semaphore s[n]; /* um semáforo por filósofo */ void philosopher (int i) /* i número de filósofo, de 0 a N 1 */ { while (TRUE) { /* repete indefinidamente*/ think(); /* filósofo está pensando */ 47

48 take_forks(i); /* pega dois garfos ou bloqueia */ eat(); /* comendo espaguete */ put_forks(i); /* coloca os garfos de volta à mesa */ } } void take_forks(int i) /* i número de filósofo, de 0 a N 1 */ { down(&mutex); /* entra em região crítica */ state[i] = HUNGRY; /* registra que o filósofo i está com fome */ test(i); /* tenta pegar os dois garfos */ up(&mutex); /* sai da região crítica */ down(&s[i]); /* bloqueia se os garfos não foram pegos */ } void put_forks(i) /* i número de filósofo, de 0 a N 1 */ { down(&mutex); /* entra em região crítica */ state[i] = THINKING; /* filósofo termina de comer */ test(left); /* verifica se o vizinho da esquerda pode comer agora */ test(right); /* verifica se o vizinho da direita pode comer agora */ up(&mutex); /* sai da região crítica */ } void test(i) /* i número de filósofo, de 0 a N 1 */ { 48

49 if (state[i] == HUNGRY && state[left]!= EATING && state[right]!= EATING) { state[i] = EATING; up(&s[i]); } } Os comentários sobre código acima são autoexplicativos, porém algumas linhas do código valem ser ressaltadas. Temos um while principal com funções para as quatro atividades dos filósofos que são: pensando, pegando os garfos, comendo e colocando os garfos de volta na mesa. Na função take_forks, vemos um teste para verificar se os garfos estão disponíveis e a decisão de pegar os talheres ou não associadas à colocação do semáforo no estado de down ou up. Na função put_forks vemos a execução da função test para verificar se o filósofo vizinho da direita ou dá esquerda podem pegar os garfos, assim a função test verifica se os vizinhos não estão comendo, para que o filósofo possa entrar do estado de EATING. Existem abordagens mais recentes para esse problema como Software Visualization que é uma programação visual, baseada em semiótica e os recursos de linguagens de programação como a Parlog86. Problemas de leitores e escritores Esse problema está muito ligado ao acesso a banco de dados. Quando temos um banco de dados, podemos ter vários acessos de leitura, mas apenas um de escrita por questões óbvias, pois se tivermos vários acessos de escrita mesmo em registros diferentes ou ainda no mesmo registro, mas em intervalos muito pequenos, teremos um banco de dados inconsistente, além disso, essa condição seria muito propícia a deadlocks. A solução clássica para esse problema é relativamente simples. Temos dois semáforos, um que poderia ser chamado db e outro mutex, o primeiro para controlar o acesso de escrita ao banco e o segundo para controlar os acessos de leitura. Quando o primeiro leitor acessar o banco, coloca em down o semáforo db e incrementa o contador de leitores no semáfora mutex. 49

50 Na medida em que outros leitores foram acessando o banco de dados, o contador é incrementado, quando eles deixam de acessar o banco, o contador é decrementado. Quando o último leitor deixa o acesso, ele muda a condição do semáforo db para up e assim um escritor do banco de dados, caso exista algum nesse momento, está livre para fazer um acesso de escrita. Essa abordagem é eficiente caso não tenhamos uma quantidade muito elevada de acessos de leitura ao banco, pois do contrário, nunca ocorrerá um acesso de escrita devido à condição de mútua exclusão entre os dois processos. Uma solução para essa fragilidade do algoritmo seria quando um leitor for acessar o banco e já houver um processo de escrita esperando a liberação do mesmo, esse processo é colocado em espera, sendo executado só após a liberação e execução do processo de escrita, dessa forma o escritor só esperaria pelos processos de leitura que já estivessem em execução na sua chegada. Um ponto fraco dessa abordagem é que, apesar dela diminuir a concorrência entre processos, tem o desempenho comprometido. Segue o código que apresenta a solução descrita acima para o problema de acessos de leitura e escrita: typedef int semaphore; /* os semáforos são tipos de especiais de int */ semaphore mutex = 1; /* controla o acesso ao 'rc' */ semaphore db = 1; /* controla o acesso ao banco de dados */ int rc = 0; /* número de processos de leitura ou desejando ler */ void reader(void) { while (TRUE) { /* repete indefinidamente */ down(&mutex); /* obtém acesso exclusivo ao 'rc' */ rc = rc + 1; /* mais um leitor agora */ if (re == 1) down(&db); /* se esse é o primeiro leitor */ up{&mutex); /* libera o acesso exclusivo ao 'rc' */ 50

51 read_data_base(); /* acessa os dados */ down(&mutex); /* obtém acesso exclusivo ao 'rc' */ rc = rc 1; /* um leitor a menos agora */ if (rc == 0) up(&db); /* se esse é o ultimo leitor */ up(&mutex); /* libera acesso exclusivo ao 'rc' */ use_data_read(); /* região não-crítica */ } } void writer(void) { while (TRUE) { /* repete indefinidamente */ think_up_data(); /* região não crítica */ down(&db); /* obtém acesso exclusivo */ write_data_base(); /* atualiza os dados */ up(&db); /* libera acesso exclusivo */ } } Vale ressaltar que nesse código a verificação feita pela função if da ocorrência de finalização do último processo de leitura, que libera o acesso exclusivo ao banco, colocando o semáforo mutex em up, para que caso houver um escritor em condição de espera, o mesmo coloque o semáforo em down (acesso exclusivo) e inicie a gravação no banco de dados. Existem variações nesse código justamente para privilegiar seja o controle de acesso aos recursos seja o desempenho do processo, como já discutido. 51

52 O código acima não privilegia os acessos de escrita, pois eles necessitam esperar até o último acesso de leitura deixar o processo para poder assim acessar o banco de dados. O Problema do Barbeiro Dormindo Esse problema é ilustrado pela seguinte situação. Temos uma barbearia com apenas um barbeiro, uma cadeira de barbeiro e n cadeiras de espera. Se não há clientes, o barbeiro senta na cadeira de barbeiro e dorme. Se um cliente chega, ele acorda o barbeiro que começa cortar o seu cabelo. Se outros clientes chegam enquanto o barbeiro está realizando um corte, eles sentam nas cadeiras de espera ou saem se não houver cadeiras de espera disponíveis. O problema é criar uma lógica de modo a programar o barbeiro e os clientes sem entrar numa condição de corrida (race condition). Esse problema é similar a muitas situações de controle de filas, como por exemplo, um software de controle de ligações num Call Center. Uma solução para esse problema utilizaria três semáforos: clientes que conta os clientes aguardando (excluindo o cliente na cadeira de barbeiro), barbeiros, número de barbeiros (0 ou 1) que pode ficar numa condição de ocioso (dormindo) ou trabalhando(cortando cabelo) e mutex que é usado como exclusão mútua. É necessário ainda a variável waiting que conta também a quantidade de clientes esperando, que é essencialmente uma cópia dos clientes. A razão para essa variável é a impossibilidade de ler um valor corrente de um semáforo. Nessa solução, um cliente que entra na barbearia tem de contar o número de clientes esperando. Se for menor que o número de cadeiras, ele permanece, caso negativo, ele deixa a barbearia. 52

53 Segue um código que contempla a solução para o problema do Barbeiro Dormindo: #define CHAIRS 5 /* número de cadeiras para clientes esperando */ typedef int semaphore; /* os semáforos são tipos de especiais de int */ semaphore customers = 0; /* número de clientes esperando pelo serviços */ semaphore barbers = 0; /* número de barbeiros esperando por clientes */ semaphore mutex = 1; /* para exclusão mútua */ int waiting = 0; /* clientes estão esperando (não tendo os cabelos cortados) */ void barber(void) { while (TRUE) { 0 */ down(&customers); /* entra no estado de dormindo se o número de clientes é down(&mutex); /* obtém o acesso à variável waiting */ waiting = waiting 1; /* decrementa a contagem de clientes esperando */ up(&barbers); /* um barbeiro está pronto para cortar um cabelo */ up(&mutex); /* libera a variável 'waiting' */ cut_hair(); /* corta cabelo (fora da região crítica) */ } } void customer(void) { down(&mutex); /* entra na região crítica */ if (waiting < CHAIRS) { /* se não há cadeiras livres, saia */ 53

54 waiting = waiting + 1; /* incrementa a contagem de clientes esperando */ up(&customers); /* acorda o barbeiro se necessário */ up(&mutex); /* libera o acesso à variável 'waiting' */ down(&barbers); /* dorme se o número de barbeiros livres é 0 */ get_haircut(); /* está sentado e atendido */ } else { up(&mutex); /* a barbearia está cheia; não espere */ } } Nesse código podemos ressaltar os seguintes pontos: o código barber que é um loop que na medida em que se vai cortando o cabelo dos clientes vai decrementando o número dos mesmos e também liberando a função waiting ; o código costumer que testa o número total de cadeiras para verificar se é maior que o número de clientes esperando através do operador if, caso número de cadeira for menor ou igual ao número de clientes esperando, nega-se o acesso do cliente (processo) através do semáforo mutex. Na teoria de sistemas operacionais existem várias outras situações usualmente ilustradas através de exemplos envolvendo objetos, pessoas e ações, que passam a ser elementos de uma representação de um problema de comunicação interprocessos. Apenas a título de informação temos o problema dos fumantes (PATIL 9, 1971) onde temos três fumantes e um agente, onde cada fumante tem indefinidamente apenas dois dos três elementos que os habilitaria a fumar, a saber, o papel, o tabaco e o fósforo. O agente em cada ciclo disponibiliza um elemento que compõe um cigarro pronto para ser fumado. Por exemplo, se o agente disponibilizar o fósforo, o fumante que tiver o papel e o tabaco, toma o fósforo e compõe o cigarro pronto para ser fumado. O mesmo processo ocorreria com os outros fumantes. 9 Dr. Suhas S. Patil nascido em 1944 em Jamshedpur, Jharkhand, India, é um empreendedor no Silicon Valley, investidor e filantropo. Ele fundou a companhia Cirrus Logic. Recebeu seu bacharelado em engenharia no Indian Institute of Technology, mestrado e doutorado no MIT. 54

55 Nessa alegoria, o agente seria o sistema operacional e os fumantes processos ou threads. Esse problema é resolvido, como usual, utilizando semáforos, um para cada item do cigarro e um mutex. Podemos também citar o problema do Jantar dos Canibais, onde os canibais têm no caldeirão certa quantidade M de missionários cozidos, quando o canibal está com fome, ele vai até o caldeirão e se o mesmo estiver provido de missionários ele come, senão ele acorda o canibal cozinheiro para preparar mais missionários cozidos. Nesse caso temos como solução possível, uma que utilizaria um semáforo para controlar o caldeirão cheio, um semáforo para controlar o caldeirão vazio e um semáforo mutex. Eles são sincronizados adequadamente através de uma função while. Os problemas apresentados até o momento em ambientes monoprocessados e suas respectivas soluções adquirem novas facetas quando os tratamos em ambientes de processamento distribuído, com soluções distintas, mas é importante termos esses conceitos claros para podermos explorar com mais clareza os mecanismos de sincronização e prevenção da ocorrência de deadlocks, race condition e starvation em ambiente de cluster. Escalonamento de processos ou threads Um dos desafios em se desenvolver um sistema operacional é estabelecer o escalonamento dos processos, isto é, quando e por quanto tempo um processo fará uso dos recursos da CPU. Para nós compreendermos o conceito de escalonamento precisamos conhecer que existem dois tipos de processos relacionados a esse tema, processos computer-bound e processos I/O bound, o primeiro possuindo longas rajadas de utilização de CPU com esporádicos usos de E/S e o segundo com curtas rajadas de uso de CPU e freqüentes usos de E/S. Naturalmente os processos I/O bound possuem um melhor uso e desempenho de CPU, pois enquanto os processos estão utilizando algum dispositivo de E/S, a CPU pode tratar e executar outros processos. 55

56 A necessidade do escalonamento Na criação de um processo. Existe a decisão de quem será tratado primeiro, o processo pai ou processo filho. Na necessidade de decidir qual processo será tratado entre aqueles que estão prontos quando um processo deixa de utilizar os recursos. Quando um processo é bloqueado por dispositivo de E/S, por um semáforo ou por qualquer outra razão, outro processo precisa ser escolhido para ser executado em seu lugar. Quanto uma interrupção de E/S ocorre, o dispositivo de escalonamento precisa decidir se o processo que estaria esperando a interrupção de E/S será executado ou outro processo terá a prioridade no uso da CPU. As decisões tomadas pelo dispositivo de escalonamento ocorrem a cada ciclo de clock do processador. Temos também os conceitos de dispositivos de escalonamento preemptivos e não preemptivos. Um dispositivo de escalonamento não-preemptivo executa o processo indefinidamente até ele ser bloqueado, por exemplo, aguardando outro processo, ou quando ele libera o recurso voluntariamente. Já o escalonamento preemptivo estabelece um tempo de execução para cada processo, tendo a autonomia para parar o processo e para passar o tempo de acesso à CPU para outro. Podemos considerar três ambientes que requerem escalonamentos distintos: Em lote Interativo Tempo Real Existem algumas características que são desejáveis para qualquer tipo de processamento que seriam equidade, o cumprimento da política estabelecida e o uso máximo de todos os recursos, isto é, a CPU, memória, dispositivos de E/S (entrada e saída) que devem ser utilizados o maior tempo possível. 56

57 Escalonamento em processamento em lote Esse tipo de processamento não é muito utilizado ultimamente, a não ser em computadores de grande porte (mainframes). Porém podemos afirmar que renderização de imagens pode ser considerada como um processamento batch, sendo uma das aplicações das mais utilizadas em clusters com um desempenho satisfatório. Provavelmente um dos mais simples algoritmos de escalonamento seria o primeiro que chega; primeiro a ser processado, por certo esse é uma técnica não preemptiva de escalonamento. O primeiro processo que requisita o uso da CPU, tem o uso da mesma até a finalização ou bloqueio do mesmo para, por exemplo, acessar algum dispositivo de E/S. Quanto isso ocorre o processo que está na primeira posição numa fila passa a ser atendido. Esse algoritmo embora de simples implementação, tem uma série de fragilidades e situações em que teria um desempenho não satisfatório. Outro algoritmo seria o menor job primeiro. Apesar de não ser preemptivo, ele prioriza os processos menores, fazendo assim que o sistema tenha um melhor desempenho como um todo. Porém o desempenho desse algoritmo depende da sequencia em que os processos chegam e são tratados. Uma versão preemptiva do menor job primeiro seria o menor tempo restante para ser finalizado, nesse caso o sistema precisa saber previamente qual o tempo restante de cada processo. Se um job chega e tem um tempo para ser finalizado menor do que está em execução, o job em execução é bloqueado e o que chega é executado. Com essa versão obtém-se um bom desempenho para pequenos jobs. Temos também o processo de escalonamento em três níveis, onde um escalonador de admissão (admission scheduler) decide qual job será aceito pelo sistema, os não aceitos naquele momento, são colocados numa fila de entrada até serem selecionados. O escalonador precisa distinguir entre jobs CPU-bound e jobs I/O - bound. Esse mecanismo seria o primeiro nível de escalonamento. Quando os jobs são colocados em fila, eles são convertidos em processos e postos em memória. Podemos chegar numa condição que não teremos mais espaço em memória para colocar os processos em espera, dessa forma eles são armazenados em disco, mecanismo conhecido como swap de memória ou paginação. 57

58 O segundo nível de escalonamento é o decide qual processo será colocado ou não em memória, também chamado de escalonamento de memória. O terceiro nível de escalonamento é o que decide qual processo em memória será o próximo a ser executado. Existem outros algoritmos de escalonamento como o Backfilling que em linha geral procura executar alguns processos que não estão no topo da fila, visando um melhor aproveitamento da CPU. Temos também o Earliest Deadline First (EDF) que organiza os jobs por prioridade, executando sempre o job com maior prioridade primeiro. A prioridade é inversamente proporcional ao deadline (tempo limite) do job, que seria o tempo que o job estabelece para ser executado. Escalonamento em Sistemas Interativos Quando pensamos em algoritmos para escalonamento em sistemas interativos, podemos utilizar os mesmos algoritmos para escalonamento de CPU em sistemas de processamento em lote. Não conseguimos ter em sistemas interativos o processo de escalonamento em três níveis, mas podemos ter dois níveis nesse tipo de sistema (escalonamento de memória e escalonamento de CPU). As técnicas de escalonamento para Sistemas Interativos usualmente focam mais no escalonamento de CPU. Escalonamento round robin: Esse é algoritmo é um dos mais antigos, simples, imparcial e amplamente utilizado para escalonamento. Para cada processo é dado um intervalo de tempo chamado quantum durante o qual o mesmo pode ser executado. 58

59 O único parâmetro com o qual se pode realizar algum ajuste é a duração do quantum. Num raciocínio simples, se estabelecemos um quantum muito curto, teremos um chaveamento excessivo de processos, diminuindo a eficiência da CPU, pois a cada troca de processo, um tempo de CPU é utilizado para liberar e alocar memória, registradores, tabelas, listas, etc. Ao passo que caso se estabeleça um quantum muito longo teremos um tempo de resposta inaceitável para processos de curta duração. Podemos pensar num quantum entre 20 a 50 milissegundos como um valor razoável para esse tipo de escalonamento. Escalonamento por prioridade: No escalonamento round robin partimos da premissa que todos os processos são igualmente importantes. No escalonamento por prioridade, é atribuída uma prioridade para cada processo, assim o processo que está pronto para ser executado e com a maior prioridade, é processado pela CPU. Como prevenção contra processos sendo executados indefinidamente, a cada ciclo de clock a prioridade do processo é decrementada ou pode-se também trabalhar com o conceito de quantum, quando tempo destinado ao processo acabar, o processo em espera com a maior prioridade é executado. As prioridades poder ser atribuídas estática ou dinamicamente. Quando falamos de atribuição estática de prioridade, estamos considerando o tipo de usuário ou atividade que requer maior ou menor prioridade. Por exemplo, se pensarmos num sistema em que os processos tratam de cifras, provavelmente os processos que trabalharem com os maiores valores terão uma prioridade maior. Já na atribuição dinâmica de prioridade, informações sobre a característica do processo, isto é, se ele é I/O-bound ou CPU- bound, assim como quanto tempo ele utiliza do quantum que é alocado para ele, estabelecem a prioridade de cada processo. 59

60 Múltiplas filas Outra estratégia de escalonamento para sistemas interativos é utilizar múltiplas filas, atribuindo certa quantidade de quantums para cada uma delas. O processo com a maior prioridade receberá apenas um quantum no primeiro ciclo de processamento. No próximo ciclo receberá dois quantums, no próximo ciclo, o processo com maior prioridade receberá quatro quantums, assim por diante. Assim se um processo com a mais alta prioridade precisa de cem quantums para realizar um job, ele receberá um quantum no seu primeiro ciclo de processamento, no próximo dois quantums, depois quatro, oito, dezesseis, trinta e dois, sessenta e quatro quantums até finalizar o seu job. Esse algoritmo evita que um processo monopolize a utilização dos recursos, especialmente de CPU, quando tem uma alta prioridade. O próximo processo mais curto (Shortest Process Next) Esse algoritmo pode também ser usado em processos em lote, que utiliza a técnica de executar os processos mais curtos primeiro que produz bons tempos médios de resposta nesse tipo de processo. A ideia desse algoritmo é utilizar a característica de processos interativos onde temos sucessivas situações de execução de um comando e uma resposta para o mesmo. Podemos assim considerar essas execuções como jobs separados e assim tratá-los com prioridade. Mas precisa-se estabelecer um critério ou uma técnica para determinar a duração dos processos. Uma abordagem seria considerar o comportamento anterior do processo, calculando uma média ponderada dos tempos de execução passados. Nessa técnica pode-se escolher quantos processos já executados serão considerados no cálculo. Essa técnica é utilizada em outras aplicações, como, por exemplo, protocolos de rede, é conhecida como aging. Escalonamento garantido Essa técnica procura literalmente dividir o tempo de CPU entre os processos que estão em execução em dado momento. Para fazer isso o sistema computa quanto tempo de CPU o processo consumiu na sua criação depois simplesmente divide esse tempo por n que seria o número de processos que estão em execução. Assim dependendo da quantidade de processos em execução, cada um deles receberá igualitariamente ciclos de processamento da CPU, podendo assim receber menos ou mais tempo dependendo da quantidade dos processos concorrentes. 60

61 Escalonamento lotérico Embora efetivo em termos de resultados, o escalonamento garantido é de difícil implementação. Assim surgiu outro algoritmo com os mesmos resultados previsíveis, mas com uma implementação muito mais simples, conhecido Escalonamento Lotérico. A ideia é simples, cada processo recebe uma quantidade de bilhetes que permitem acesso a CPU. Esses bilhetes são escolhidos aleatoriamente, dando o direito de ter 20 milissegundos de uso do processador. Para processos que precisam ter prioridade é dado um número maior de bilhetes, aumentando assim a probabilidade dos mesmos serem escolhidos e automaticamente dando mais tempo de CPU para eles. Os processos podem trocar bilhetes num ambiente onde estão trabalhando em cooperação. Essa é uma técnica bastante responsiva e eficiente. Escalonamento de compartilhamento justo (Fair-Share Scheduling) Os algoritmos até aqui analisados consideraram apenas os processos em si mesmos, não considerando os usuários que os executam. Mas isso pode influir significamente num compartilhamento adequado de uma CPU. Por exemplo, se usuário ativa 9 processos e o outro 1 processo. O primeiro terá 90% do uso da CPU e o segundo apenas 10%. Para prevenir esse tipo de condição alguns sistemas consideram no escalonamento a quem pertencem os processos. Assim se for garantido para 2 usuários 50% da CPU, eles terão esse recurso contratado independente de quantos processos cada um colocará em execução. 61

62 Escalonamento em sistemas em tempo real Sistemas em tempo real, usualmente recebem uma requisição a qual precisa ser respondida num intervalo de tempo muito curto, como por exemplo, a execução de uma música de um CD, uma resposta de um jogo de computador a uma ação de quem está o executando, etc. Eles podem ser divididos em hard real times que são aqueles totalmente rígidos em relação aos tempos de resposta (deadlines) e em soft real times significando que se pode ultrapassar o deadline algumas vezes sem comprometer as funcionalidades do sistema. Em linhas gerais, os processos em tempo real são conhecidos a - priori quanto ao comportamento e tempo de execução, usualmente são de execução curta não ultrapassando a um segundo. Os processos são ativados de modo geral por um evento externo que solicita uma atividade a um controlador de processos (scheduler) que garante que cada processo seja realizado dentro do seu deadline. Os sistemas em tempo real podem ser periódicos que possuem intervalos regulares entre os processo e aperiódicos em que os intervalos são imprevisíveis. Obviamente os sistemas periódicos são mais fáceis de serem implementados e podem ser calculados pela seguinte fórmula: Fórmula 1 Onde m são os eventos periódicos onde o evento i ocorre no período Pi e requer Ci segundos para executar cada evento. Se um sistema em tempo real satisfizer as condições dessa fórmula, dizemos que ele é escalonável (schedulable). 62

63 Quando falamos em sistemas em tempo real, podemos considerar o tema multimídia como central. Todos os sistemas multimídias requerem uma execução dos processos em intervalos curtos e periódicos para garantir uma boa imagem e som como resultado. Assim os sistemas digitais encontrados nos CD s e especialmente nos DVD s são exemplos clássicos de dispositivos que demandam um processamento em tempo real. Temos como um avanço uma tecnologia ainda em difusão que é o Video on Demand (VoD) que apesar ser uma solução muito interessante chega ainda a poucos lares de usuários, pelo menos no Brasil. O sistema consiste em servidores com uma capacidade significativa de disco, na ordem de Terabits, que armazenam arquivos de som e imagem nos mais diversos formatos, tendo conexões de relativa velocidade, pelo menos 1 Mbps (megabits por segundo) com os assinantes que podem assistir em tempo real o conteúdo dos Vídeos Servers. Como servidores VoD e IPTV podem ser implementados em clusters de Linux, abordaremos esses temas nesse trabalho. Em primeiro lugar, precisamos estabelecer a diferença entre as tecnologias. Enquanto o VoD seria um repositório vídeos armazenados podendo ser comparado a uma grande biblioteca de DVD s transmitindo usualmente através pacotes unicasts que é uma transmissão de pacotes um para um, a IPTV é a transmissão de streams de vídeo podendo ser ao vivo através de multicast que é uma transmissão de pacotes de um para muitos. Dessa forma IPTV consome muito menos banda passante do que a VoD devido a modo de transmissão que utiliza. Em termos de uso da população em geral, o IPTV mostra-se mais difundido. Nos últimos anos temos visto um crescimento mais consistente do uso dessa tecnologia, especialmente com a consolidação e difusão dos aparelhos IPTV. Estimase que teríamos cerca de 60 milhões de usuários em todo o mundo que utilizarão essa tecnologia em 2009 (Parks Associates). Esse aumento de procura está ligado à oferta de triple-play (Voz Telefone, Dados Internet e Imagem TV) por algumas operadoras e também a interatividade proporcionada pela IPTV. Além disso, a tecnologia de IPTV está migrando para outras aplicações como, por exemplo, IP Surveillance (Vigilância), onde a IPTV é uma componente dessa solução, substituindo os tradicionais circuitos fechados de TV. 63

64 Avançando um pouco mais nas diferenças das tecnologias enquanto o VoD utiliza o RSTP (real-time streaming protocol) para a sinalização e RTP (real-time protocol) para a transmissão do fluxo (stream) de vídeo que são protocolos originalmente utilizados em Voz sobre IP (VoIP), a IPTV utiliza o IGMP (Internet Group Management Protocol) que um protocolo para controle de multicast em redes locais. Apesar de diferenças significativas as duas tecnologias compartilham quase os mesmos problemas quando tratamos de qualidade de Voz e Imagem, que seria o atraso, a perda de pacotes e especialmente o jitter que seria a variação dos intervalos entre os pacotes de fluxo de vídeo e de voz que é mais prejudicial à qualidade do serviço do que um atraso constante dos pacotes mesmo que sejam mais longos. Existem técnicas na engenharia de redes para prover qualidade de serviço para aplicações sensíveis ao tempo (QoS), que visam garantir prioridade e intervalos regulares entre esse tipo de tráfego. Também esse tipo de prioridade também precisa ser garantida nos servidores que alojam esse tipo de aplicação, seja na computação convencional, seja em sistemas distribuídos. Grande parte da tecnologia para sistemas em tempo real está no formato, compressão e correção de erros dos arquivos multimídia. Sem esses recursos seria impossível termos capacidade de armazenagem e transmissão desses arquivos assim como uma qualidade de Voz e Imagem aceitáveis. Para entendermos como são estruturados os arquivos multimídia, precisamos conhecer como eles são codificados, ou como a imagem e o som que a princípio são sinais analógicos são transformados em sinais digitais para que sejam tratados por computadores e sistemas de redes. Codificação de Áudio Em termos simples, a codificação de áudio seria transformar um sinal elétrico analógico que corresponde a determinado som, numa sequencia de códigos digitais, portanto 0 s e 1 s que correspondem tomadas por amostragem das amplitudes desse sinal no tempo (sampling). Usaremos a digitalização de uma senóide para ilustrar o conceito. 64

65 Figura 1 Na figura 1, no gráfico a temos a escolha dos pontos de amostragem do sinal, no gráfico b temos esses pontos transformados em códigos binários simbolizados pelas linhas verticais, no gráfico c temos o resultado real de um processo de sampling que nunca corresponderá exatamente ao sinal original, mas que para sensibilidade do ouvido humano corresponde a uma qualidade de áudio muito próxima do sinal analógico original como ilustrado no gráfico d. Podemos pensar em aumentar o número de amostragens, porém isso gera um tipo de distorção conhecida como ruído de quantização. Como exemplos de codificação, podemos utilizar a codificação de telefonia analógica e de Compact Disks (CD s). A telefonia utiliza a técnica de digitalização de voz conhecida como PCM (Pulse Code Modulation) que utiliza amostragens de 7 bits (Estados Unidos e Japão dentre outros) e 8 bits (Europa e Brasil dentre outros) vezes por segundo, gerando respectivamente canais digitais de Voz de 56 e 64 Kbps (kilobits por segundo). Com essa codificação sinais acima de 4 khz são perdidos, porém apesar da faixa de frequência audível ser de 20 Hz a 20 khz, conseguimos uma qualidade de Voz razoável com essa técnica de codificação. Quando falamos em CD s temos amostragens por segundo que nos dá uma faixa de frequência na ordem de 22 khz, com certeza provendo uma qualidade de áudio muito superior ao das ligações telefônicas que utilizam canais digitais. 65

66 Temos técnicas de compressão de Voz que proporciona economia em armazenagem e na transmissão desse tipo de arquivo como, por exemplo, os protocolos G.729 ou G.726 para telefonia e o muito conhecido MP3 (MPEG Layer 3) para compressão de músicas, falas, etc. De modo geral as técnicas de compressão de Voz trabalham com a redução da redundância da informação através de métodos como codificação, reconhecimento de padrões e predição linear para reduzir o tamanho dos arquivos a serem executados ou pacotes a serem transmitidos. Codificação de vídeo Para entender a digitalização de imagens precisamos conhecer os conceitos básicos da transmissão e recepção eletrônica de vídeo, isto é, o modo de processamento de imagens nos televisores e monitores convencionais de computador. Abstraindo-nos dos conceitos da eletrônica ao máximo possível, pois não é o foco de nosso trabalho, um televisor ou mesmo um monitor convencional possuem um Tubo de Raios Catódicos (CRT - Cathode Ray Tube). Numa TV temos o que chamamos varredura vertical e horizontal que seria a composição quadro a quadro das imagens, nos dando a impressão de movimento. O conhecido sincronismo vertical e horizontal determina em que ponto da tela a imagem está sendo composta, por isso quando dizemos que existe um problema de sincronismo, temos como resultado uma imagem indistinta ou até mesmo apenas faixas na tela. No sistema PAL temos uma frequência de 25 quadros/sec. Com essa velocidade de troca de quadros temos uma imagem trêmula. Os televisores utilizam a técnica conhecida como intercalamento (interlacing), as linhas pares são transmitidas num quadro e as linhas ímpares num outro. Assim temos uma frequência de 50 quadros/sec que elimina a impressão de tremor da imagem aos olhos humanos. O desenho da imagem é composto através do bombardeamento de elétrons numa superfície fosforescente que gera um ponto brilhante na tela. 66

67 Esses pontos compõem as imagens através do desvio de suas trajetórias por eletromagnetismo provido por um componente eletrônico conhecido como bobina defletora. Nos televisores coloridos temos 3 canhões de elétrons com as cores RGB (Red, Green, Blue) que conseguem compor todas as outras cores, curiosamente não sendo as cores conhecidas popularmente como primárias que seriam o vermelho, o azul e o amarelo, pelo menos nas artes plásticas. Apenas a título de esclarecimento, o reconhecimento das cores primárias não é um conceito físico mais fisiológico relacionado à reação do olho em relação à luz e seus diversos comprimentos de onda que compõe um número quase infinito de cores. O olho humano tem três receptores de luz conhecidos como cones, sendo que cada um deles respondem ao comprimento de onda das cores vermelha, verde e azul sendo essas consideradas como primárias tratando-se de fontes de luz, por isso que os tubos de imagem utilizam o padrão RGB. Tratando-se de monitores de computador, apesar de possuírem o mesmo aparato eletrônico dos televisores, diferentemente desses, eles traduzem sinais digitais em imagem. Os monitores de computador trabalham com o conceito de pixel que é o menor elemento que compõe uma imagem ou caractere num monitor de computador, por exemplo, se um ícone tem 32 pixels de altura e 32 pixels de largura ele conterá um total de 1024 pixels. As imagens são formadas nos computadores, através de variações de cor e brilho, também conhecidos como crominância e luminância dos pixels. Para garantir a persistência da imagem adequada ao olho humano, como já mencionado, precisamos ter pelos 25 quadros/sec utilizando a técnica de intercalamento, porém como os computadores podem armazenar as imagens em memória, consegue-se obter uma frequência de troca de quadros de 75 vezes por segundo, não necessitando assim do intercalamento. Assim dizemos que os monitores de computador utilizam um escaneamento progressivo. 67

68 Os monitores de computador têm o conceito de resolução que seria quantas linhas o monitor teria na vertical e na horizontal, por exemplo, um monitor com resolução 800x600 significa que tem 800 linhas na vertical e 600 linhas na horizontal. Obviamente quanto mais linhas ou quanto maior a resolução, melhor a qualidade de imagem. Quantidade de bits para compor uma imagem é usualmente é alta, uma imagem num monitor com resolução de 1024x768 tendo um pixel com tamanho de 24 bits, numa frequência de 25 quadros/sec, necessitaria de 472 Mbps para ser transmitida. Daí a obrigatoriedade tecnológica de trabalhar com compressão de imagens nos computadores e nas redes. Compressão de Vídeo Todo sistema de compressão de arquivos de imagem precisa ter dois algoritmos: um de compressão e outro de descompressão, na literatura em geral, eles são chamados de codificação (encoding) e decodificação (decoding). Entre esses dois algoritmos temos o conceito de assimetria, por exemplo, se estivermos falando VoD, o sistema de codificação pode ser lento e despender um hardware mais poderoso e caro, porém o processo de decodificação precisa ser rápido e concebido para ser executado num hardware mais acessível em termos de preço. Por outro lado, um sistema de vídeo conferência precisa ter tanto a codificação e a decodificação em tempo real, necessitando assim de hardware e software apropriados para esse tipo de aplicação. Um segundo tipo de assimetria na compressão de vídeo, seria que a imagem originalmente codificada não precisa necessariamente ser exatamente igual quando a mesma for decodificada, de fato isso raramente ocorre, porém tal assimetria é aceitável em termos de acuidade do olho humano. Há na maioria dos casos uma leve perda de qualidade entre a imagem original e a que é visualizada após ser descomprimida num determinado sistema, quando isso ocorre dizemos que o sistema é lossy. De fato, os codificadores de uso geral e comercial são todos lossies, mas existem lossless codecs na compressão de vídeo. 68

69 Padrão JPEG Um dos mais conhecidos padrões de compressão de imagem é o JPEG (Joint Photographic Experts Group). O processo de compressão do JPEG não é trivial assim apresentaremos o mesmo de uma forma simples, de modo a satisfazer o propósito desse trabalho no que concerne à codificação de imagem. Existem muitos padrões para produzir-se esse tipo de arquivo, mas o mais utilizado é o JFIF (JPEG File Interchange Format). Segue uma descrição sucinta desse processo de codificação: A representação das cores é traduzida do padrão RGB para Y CbCr, que são modelos matemáticos conhecidos como espaços de cores (Color Spaces), sendo sistemas arbitrários de cores, não utilizados na interpretação usual das mesmas. No caso do modelo Y CbCr, o Y que é o componente de luminância representando o brilho e dois componentes de crominância (Cb e Cr) representando a cor. Lembrando que esse padrão é utilizado na codificação das imagens de TV Digital e DVD, sendo similar ao padrão PAL de televisão analógica. A resolução da crominância é reduzida, normalmente pela metade. Isso reflete o fato que os olhos são menos sensíveis a pequenas alterações na cor do que pequenas alterações no brilho. A imagem é dividida em blocos de 8x8 pixels e cada bloco, dados os componentes Y, Cb e Cr dos mesmos, passam por uma transformada conhecida como DCT (Discrete Cosine Transform). Uma transformada DCT similar à transformada de Fourier que produz um tipo de espectro de frequência espacial. A razão de se utilizar esse recurso matemático que trabalha com 3 dimensões (espacial) é porque na codificação do JPEG temos 3 elementos, a representação Y CbCr. Os componentes da amplitude da frequência são quantizados, que é a representação numérica de um sinal analógico. O olho humano é muito mais sensível a pequenas variações de cor e brilho em áreas amplas do que variações em alta frequência de brilho. Portanto, a magnitudes dos componentes de alta frequência são armazenadas com menor acuidade do que componentes de baixa frequência. A qualidade estabelecida no codificador (por exemplo, 50 ou 90 numa escala de 0 a 100 na biblioteca do Independente JPEG Group ) afeta o quanto a resolução de cada componente de frequência será reduzido. Se uma configuração de excessiva baixa qualidade for utilizada, todos os componentes de alta frequência são descartados de uma vez. 69

70 Os dados resultantes dos blocos 8x8 são ainda comprimidos com um algoritmo lossless, uma variação da codificação de Huffman 10, um algoritmo de codificação de entropia. Padrão MPEG Toda essa teoria e conceitos até agora apresentados no que concerne padrões tradicionais de transmissão e compressão de imagem, servirão de base teórica para apresentarmos o padrão de compressão de vídeo MPEG (Motion Picture Experts Group), que é um dos principais padrões de compressão de vídeo desde O MPEG1 foi concebido para a compressão de vídeo para o sistema NTSC numa taxa de 1.2 Mbps. O MPEG2 foi criado com uma compressão de broadcasting com qualidade, em taxas de 4 a 6 Mbps, podendo ser utilizado tanto no sistema PAL como no NTSC. As duas versões se beneficiam com duas redundâncias existentes em filmes: espacial e temporal. A redundância espacial é alcançada apenas codificando cada quadro separadamente com JPEG. Uma compressão adicional pode ser obtida pelo fato que os quadros consecutivos são quase sempre idênticos (Redundância Temporal). O Sistema de Vídeo Digital usado nas câmeras digitais utiliza o padrão JPEG porque a codificação tem que ser feita em tempo real sendo muito mais rápida do que codificar cada quadro separadamente. Apesar das câmeras digitais terem uma velocidade menor do que os sistemas tradicionais de vídeo sem compressão, os últimos têm uma qualidade de imagem muito aquém daquela proporciona pelo Vídeo Digital. Por exemplo, numa cena onde temos as imagens de fundo sem alterações e um ou dois personagens movimentando-se lentamente, praticamente quase todos os pixels serão idênticos quadro a quadro. Por outro lado, se temos uma cena com ampliação e redução da visão panorâmica das imagens de fundo, essa técnica é extremamente improdutiva. Daí a necessidade de ter-se uma maneira de compensar essa movimentação nas imagens. Isso é exatamente que o MPEG faz, sendo a grande diferença entre o MPEG e o JPEG. A saída do MPEG consiste de três tipos diferentes de quadros que são processados pelo programa de visualização: 10 David A. Huffman enquanto fazia o doutorado no MIT, publicou em 1952 o artigo A Method for the Construction of Minimum-Redundancy Codes. 70

71 Quadro I (Intracoded): Contendo codificação JPEG para imagens estáticas. Quadro P (Predictive): Diferença bloco a bloco com o último quadro. Quadro B (Bidirecional): Diferença entre o último e o próximo quadro. O Quadro I é apenas imagens estáticas codificadas em JPEG, com resolução de luminância completa e a metade da resolução de crominância em cada eixo. É necessário ter Quadros I aparecendo periodicamente na saída do fluxo de imagem por três razões. A primeira, o MPEG pode ser usado para TV Broadcasting, com os espectadores podendo sintonizar os canais segundo seu desejo. Se todos os quadros dependessem do seu predecessor voltar para o primeiro quadro da transmissão, qualquer um que perdesse o primeiro quadro nunca poderia decodificar qualquer quadro subsequente. Isso tornaria impossível ao espectador sintonizar um filme depois que ele já tivesse iniciado. Segundo, se qualquer quadro estivesse tendo uma recepção com erro, não se poderia continuar com a decodificação. Terceiro, sem os Quadros I, ao realizar rápidos forward e rewind, o decodificador teria que calcular todo quadro transmitido para que ele soubesse exatamente onde ele havia parado. Como o Quadro I é possível saltar no forward e no rewind até que um Quadro I seja encontrado e iniciar-se a visualização daquele ponto, o mesmo é inserido na saída de vídeo uma a duas vezes por segundo. Os Quadros P, diferentemente, codifica a diferença entre os quadros. Eles são baseados na ideia de macroblocks (macrobloco) que cobrem 16x16 pixels em espaço de luminância e 8x8 pixels em espaço de crominância. Um macrobloco é codificado para buscar quadros anteriores, visando à diferença entre os blocos. O padrão MPEG não especifica como buscar, até onde buscar ou o quanto o quadro está coerente com a busca. Isso fica a cargo de cada implementação. Por exemplo, uma implementação pode buscar por um macrobloco na posição corrente e nos quadros anteriores, realizando uma comparação entre os quadros encontrados. Para cada posição, o número de igualdades identificadas na matriz de luminância pode ser computado. A posição com o maior escore seria declarada a vencedora, baseandose num parâmetro previamente estabelecido. Caso esse parâmetro não for alcançado poder-se-ia dizer que o macrobloco foi perdido. Naturalmente, existem algoritmos muito mais sofisticados para manusear macroblocos. 71

72 Se um macrobloco é encontrado, ele é codificado, considerando a diferença entre seu valor e do quadro anterior (para a luminância e as duas crominâncias). Essas matrizes de diferenças são então submetidas à codificação JPEG. O valor do macrobloco no fluxo de saída de vídeo é então o vetor de movimento (o quanto o macrobloco mudou de sua posição anterior em cada direção eixos x e y de crominância), seguido pelas diferenças com o quadro anterior codificadas em JPEG. Se o macrobloco não está no quadro anterior, o valor corrente é codificado em JPEG, como se fosse um Quadro I. O quadro B é similar aos Quadros P, exceto que ele permite o macrobloco de referência ser ou o quadro anterior ou o quadro posterior, num Quadro I ou um Quadro P. Essa liberdade adicional permite melhorar a compensação do movimento nas imagens, quando, por exemplo, objetos passam na frente ou atrás de outros objetos. Os Quadros B permite a um quadro ser baseado no quadro futuro. Para codificar um Quadro B, o codificador precisa manter três quadros codificados na memória ao mesmo tempo, o anterior, o corrente e futuro. Para simplificar a decodificação, os quadros precisam estar presentes no fluxo do MPEG numa ordem de dependência e não numa ordem de visualização. Assim mesmo com uma temporização perfeita, quando um vídeo é assistido através de uma rede, é requerido fazer uma buferização (buffering) no computador do usuário para reordenar os quadros numa visualização apropriada. Devido a essa diferença entre a ordem de dependência e a ordem de visualização, tentar reproduzir um filme de frente para trás não será possível sem um considerável buferização e complexos algoritmos. Escalonamento de Processos em Sistemas Multimídia Sistemas Operacionais que suportam multimídia diferem dos tradicionais em três principais aspectos: escalonamento de processos, sistema de arquivo e escalonamento de disco. Escalonamento Homogêneo de Processos O tipo mais simples de servidor de vídeo é aquele que suporta a visualização de um número fixo de filmes, todos utilizando a mesma taxa de quadros, resolução, taxa de dados e outros parâmetros também semelhantes. Sob essas circunstâncias, um simples, mas efetivo algoritmo de escalonamento seria como segue: 72

73 Para cada filme, há um simples processo ou thread cujo job seria acessar o filme no disco, um quadro de cada vez e então transmiti-lo para o usuário. Desde que todos os processos são igualmente importantes, teremos o mesmo volume de trabalho a fazer para cada quadro, bloqueando quando eles finalizarem o processo do quadro corrente. O escalonamento round robin é plenamente adequado para esse tipo de processo. A única adição necessária para um algoritmo padrão de escalonamento seria o mecanismo de temporização para garantir que cada processo seja executado na frequência correta. Um modo de obter uma temporização adequada é possuir um relógio (clock) mestre que oscila, por exemplo, 30 vezes por segundo (para NTSC). A cada ciclo do relógio, todos os processos são executados sequencialmente, na mesma ordem. Quando o processo termina o seu trabalho, ele emite uma chamada de suspensão do sistema que libera a CPU até o próximo ciclo do relógio. Até quando os processos são curtos o suficiente para que todo o trabalho seja feito dentro de um ciclo, o escalonamento round robin é adequado. Modelos Gerais de Escalonamento para Processos em Tempo Real Infelizmente o Escalonamento Homogêneo de Processos é raramente aplicável à vida real. Um número significativo usuários mudam como expectadores, tamanho de quadros variam consideravelmente devido à natureza da compressão de vídeo (Quadros I são muito maiores que Quadros P e B) e filmes diferentes podem ter diferentes resoluções. Como consequência, processos diferentes precisam ser executados em frequências diferentes, com diferentes quantidades de trabalho e com diferentes deadlines dentro dos quais o job deve ser efetuado. Essas considerações levam a um modelo de múltiplos processos competindo pela CPU, cada um com sua própria tarefa e tempo limite (deadline). Nesses modelos, assume-se que o sistema sabe a frequência na qual cada processo deve ser executado, o quanto de trabalho tem de fazer, e qual é o seu próximo tempo limite. Esse escalonamento de processos competindo entre si, alguns ou mesmo todos tendo tempos limites que devem ser cumpridos é chamado escalonamento em tempo real. 73

74 Como vimos na página 62 desse capítulo, sistemas periódicos de multimídia podem ter a alocação de CPU calculada através de uma somatória onde m é o número de processos e Pi/Ci é uma fração de CPU utilizada pelo processo i, sendo o sistema capaz de ser escalonado se a somatória for menor que 1. Até agora estamos considerando sistemas com um processo por fluxo. De fato, poderia haver dois ou mais processos por fluxo. Por exemplo, um para áudio e outro para vídeo. Eles podem ser executados em diferentes taxas e consumir diferentes quantidades de CPU por rajada. Adicionar o áudio no sistema não muda o modelo no geral, desde que se assuma que existem n processos, cada um deles sendo executados numa frequência fixa com uma quantidade fixa de trabalho necessário em cada rajada de CPU. Em alguns sistemas em tempo real, os processos têm a capacidade de antecipar-se (preempção) e outros não têm essa funcionalidade. Em sistemas multimídia, os processos são geralmente capazes de antecipar-se, significando que o processo consegue perceber que estará excedendo o seu tempo limite, podendo assim interromper o que está sendo executado naquele momento antes de finalizar o seu o quadro, assim o processo anterior pode continuar. Usualmente os sistemas em tempo real têm melhores resultados utilizando a preempção, porém eles podem a apresentar problemas de jitter caso o buffer de transmissão acabe tendo o seu limite de tamanho excedido devido ao recebimento de várias pequenas rajadas dos processos dentro de um tempo limite. Em outras palavras, o buffer precisa estar ajustado de modo a receber todas as rajadas referentes ao tempo limite de um dado processo e enviá-lo numa única operação para o usuário requisitante. Os algoritmos de sistemas em tempo real podem se estáticos ou dinâmicos. Algoritmos estáticos designam para cada processo uma prioridade pré-estabelecida e então se trabalha com essas prioridades utilizando a preempção. Algoritmos dinâmicos não utilizam prioridades fixas. 74

75 Escalonamento de Taxa Monotônica (Rate Monotonic Scheduling) O mais clássico de escalonamento algoritmo estático para processos em tempo real periódicos e preemptivos é o RMS (Rate Monotonic Scheduling). Ele pode ser utilizado para processos que satisfaçam as seguintes condições: Cada processo periódico deve ser completado dentro do seu período; Nenhum pode ser dependente de outro; Cada processo precisa ter a mesma necessidade de CPU para sua rajada; Qualquer processo não periódico não deve ter tempo limite (deadline); O processo de preempção ocorre instantaneamente sem overhead; O RMS trabalha designando prioridades para cada processo baseado na frequência em que cada um é executado, por exemplo, se um processo tem uma frequência de execução a cada 30 milissegundos, resultando em 33 execuções por segundo, sua prioridade será 33. De acordo com o algoritmo, o sistema sempre escalona os processos com a maior prioridade prontos para serem executados utilizando a preempção, se necessário. 75

76 Escalonamento Tempo Limite mais Exíguo Primeiro (Earliest Deadline First) Esse é um algoritmo de sistemas em tempo real dinâmico, dessa forma eles não possuem uma periodicidade nem requerem um mesmo tempo de execução para rajada de CPU. A qualquer momento em que um processo precisa de um tempo de CPU, ele anuncia sua presença e seu tempo limite. O algoritmo executa então o primeiro processo da lista, que é aquele mais próximo do seu tempo limite. A cada novo processo o sistema checa se o tempo limite do mesmo é menor dos que já estão lista de processos prontos a serem executados, caso seu tempo limite seja o menor, ele é executado primeiro. O algoritmo EDF (Earliest Deadline First) é mais resiliente que o RMS (Rate Monotonic Scheduling), pois o se último tiver a taxa de utilização de CPU acima de 78% não provê uma garantia de perfeita funcionalidade. Sistemas de Arquivos em ambientes multimídia Os sistemas tradicionais de armazenagem e acesso ao sistema de arquivo mostramse inadequados para sistemas multimídia, por razões como a necessidade da disponibilização do arquivo dentro de uma mesma frequência, sem atrasos e ainda necessitar-se ter funcionalidades como mover-se rapidamente para frente, mover-se rapidamente para trás e pausa. Assim um servidor de arquivos precisa atuar mais como um videocassete ou DVD Player do que um computador. Para que isso ocorra é necessário um método acesso aos arquivos como um Push Server onde o servidor de arquivos após receber as informações para localização e buferização do arquivo empurra o mesmo para o usuário, podendo então realizar as operações de equipamentos tradicionais de multimídia como um VCR, diferentemente do acesso tradicional a arquivos onde o usuário após localizar o arquivo que deseja abrir, o traz para o seu computador (Pull Server). 76

77 Figura 2 Pull Server Push Server Armazenagem de arquivos em Sistemas Multimídia Usualmente os arquivos multimídia são muito grandes, eles são na maioria das vezes escritos uma vez e lidos muitas, tendo a tendência de serem acessados sequencialmente. Sua reprodução deve também alcançar critérios estritos de qualidade serviço. Juntos, esses requerimentos sugerem um desenho diferente de sistema de arquivo daquele utilizado nos sistemas operacionais tradicionais. Temos modelos para um único disco ou para vários. Armazenagem de arquivos multimídias num único disco O pré-requisito para ter-se uma reprodução de um arquivo multimídia de qualidade seria executar o mesmo na velocidade solicitada e sem jitter. Por esse motivo, teremse múltiplos acessos ao disco durante um quadro não é desejável. Uma forma de eliminar acessos ao disco durante a execução de um arquivo multimídia é o uso de arquivos contíguos. Sendo essa forma de acesso apropriada apenas para arquivos de vídeo. Porém, como usual, se tivermos numa reprodução a presença de vídeo, áudio e texto, se os mesmos estiverem gravados em arquivos contíguos separados, haverá uma alternância no acesso aos arquivos de vídeo, áudio e texto que poderia causar jitter. 77

78 Para minimizar esse efeito utiliza-se uma técnica também usada em VoIP (Voice Over IP) conhecida como interleaving (intercalamento), onde arquivos de textos de igual tamanho são colocados entre os arquivos de áudio e vídeo, mantendo assim a frequência da reprodução e evitando o jitter. Figura 3 Essa organização de arquivo requer a utilização mais recurso de E/S de disco e buffer, mas a qualidade da reprodução compensa essa utilização adicional dos recursos de máquina. Vale também ressaltar que para esse modelo, o acesso randômico, moverse rapidamente para frente, mover-se rapidamente para trás não são possíveis. Para arquivos não contíguos contemplaremos duas organizações de arquivos multimídia. A primeira delas é conhecida como modelo de blocos pequenos. Nessa organização o tamanho de bloco escolhido deve ser consideravelmente menor do que a média do tamanho de um quadro, mesmo para Quadros P e quadros B. A ideia é ter numa estrutura de dados, um índice de quadros por vídeo. Uma vez que os quadros têm tamanhos diferentes, o índice deve conter também o tamanho do quadro em quantidade de blocos. Figura 4 78

79 A outra forma organização de arquivos multimídia para arquivos não contíguos é armazená-los em grandes blocos de disco. Nessa situação, múltiplos quadros são colocados num bloco. Um índice é ainda requerido, porém um índice de blocos e não de quadros, índice esse semelhante ao indexador de arquivos tradicionais, conhecido como i-node (index node) que é um array que lista os atributos e endereço no disco dos blocos de arquivos. No caso de arquivos multimídia, uma informação adicional é requerida, que seria qual quadro está no início de cada bloco, fazendo assim a localização dos mesmos. No modelo de blocos grandes temos duas variações, uma em que os quadros não são separados entre os blocos e outra que eles são divididos entre os mesmos. Figura 5 Podemos resumir as vantagens e desvantagens desses modelos da seguinte forma: Indexação por Quadro: Consumo alto de RAM, pequeno desperdício de disco. Indexação por Bloco (Sem separação de quadros entre os blocos): Baixo consumo de CPU e maior desperdício de espaço em disco. Indexação por Bloco (Com separação de quadros entre os blocos) Baixo consumo de RAM, sem desperdício de disco, mas com buscas extras por quadros. 79

80 A alternativa para minimizar os efeitos do uso excessivo de memória RAM seria a paginação, que é armazenar em disco dados da memória RAM quando a mesma atinge o seu limite, o termo paginação também vem da ideia que a memória RAM é dividida em pequenas partições facilitando assim o gerenciamento da mesma. Para facilitar e otimizar as buscas dos quadros quando falamos em indexação por blocos, onde teremos mais do que um quadro por bloco ou mesmo quadros divididos entre blocos, operação que requer quadros contíguos, uma solução seria usar uma buferização circular ligeiramente maior que o tamanho do bloco, assim o bloco onde está quadro pretendido é colocado em buffer, dessa forma a busca e transmissão do quadro em questão é viabilizada, consumindo menos recursos. Cache em Sistemas Multimídia Uso tradicional do cache em Sistemas Multimídia seria sem propósito, isto é, colocar um bloco em cache esperando que o mesmo seja reutilizado não seria produtivo tendo em vista a dinâmica desse tipo de sistema. Porém quando falamos em dois espectadores assistindo um mesmo filme, com um deles iniciando 2 segundos após o outro, a acessar o mesmo arquivo multimídia, a tecnologia e o propósito do cache passam a ser interessantes, porque um bloco acessado pelo primeiro, se colocado em cache será acessado de maneira muito mais rápida e com mais performance que o segundo caso acessasse o disco novamente. Em suma, se temos dois usuários acessando um mesmo arquivo multimídia num intervalo muito pequeno, a tecnologia de cache pode ser utilizada para otimizar esse acesso. Outro uso para o cache de arquivos seria o fato dos arquivos de filmes, devido ao seu tamanho, serem armazenados em CD s e DVD s e apenas copiados para o disco quando solicitados. Esse processo, porém toma um tempo significativo. Assim os servidores mantêm em disco uma cópia dos vídeos mais demandados para aperfeiçoar essa operação. Apesar de atualmente termos storages da ordem de Terabytes que evitaria a armazenagem de arquivos em mídias de acesso mais lento, eles ainda não são acessíveis em termos de custos para todos os segmentos de negócio. Podemos também manter em disco os primeiros minutos de todos os vídeos disponíveis, dando tempo assim para cópia dos mesmos na íntegra do CD ou DVD para o disco, quando solicitados. 80

81 Vale ressaltar que estamos abordando aqui duas modalidades de cache. A primeira é o cache convencional que é uma área de armazenamento temporária de acesso mais rápido do que ao disco onde são colocados os dados mais frequentemente utilizados, que no caso dos sistemas multimídia é usado com um propósito ou objetivo diferente dos sistemas tradicionais, como explanado acima. Na segunda modalidade o disco rígido é considerado um cache para mídias de acesso mais lento como o CD ou o DVD. Escalonamento de acesso a disco em Sistemas Multimídia Diferentemente de sistemas convencionais o escalonamento estático de acesso ao disco em sistema multimídia é extremamente previsível pois os quadros tem um tempo fixo para serem executados dentro das técnicas de codificação de vídeo. Assim existe um ciclo para o acesso ao disco conhecido como rounds. Nesse intervalo de tempo, um quadro de cada fluxo de vídeo é executado, podendo assim vários vídeos acessar o disco ao mesmo tempo. Esse conceito é válido para vídeos com as mesmas características. Quando tratamos de resolução e velocidade de quadros diferentes, precisamos de um mecanismo de alocação dinâmica. Nesse caso, no momento da leitura do quadro será necessário saber quanto tempo o mesmo precisaria para ser executado, que é o tempo limite (deadline). Como os fluxos de vídeo têm características diferentes, não é possível o acesso em paralelo de vários quadros de fluxos de vídeo diferentes, assim o sistema precisa escolher qual bloco executar dentro de parâmetros préestabelecidos. Dois fatores são considerados para realizar essa escolha: o deadline e o cilindro do disco. Manter a escolha no mesmo cilindro otimiza o tempo de busca em disco mas pode comprometer o tempo limite (deadline). Assim são necessários algoritmos que equilibrem esses dois parâmetros, como por exemplo, o scan-edf. 81

82 Fundamentos de Sistemas Operacionais com Processamento Distribuído A apresentação dos conceitos referentes ao processamento convencional e executado em único um computador, abstraindo-nos da tecnologia de multinúcleo e multiprocessadores, nos servirá como fundamento teórico para identificarmos as particularidades e funcionalidades de Sistemas Operacionais Distribuídos, ressaltando novamente que por uma questão de abordagem do nosso trabalho, que não faremos aqui distinção entre sistemas distribuídos e clusters, como já explanado no início do capítulo. Redes de Computadores Antes de avançarmos nos temas que são comuns aos ambientes monoprocessados e distribuídos, precisamos abordar tecnologia responsável pela comunicação entre os computadores que compõe os sistemas distribuídos que poderia ser chamada de Redes de Computadores. Tendo em vista a amplitude da disciplina, esse trabalho abordará apenas os conceitos e tecnologias que são foco dessa pesquisa. Vamos partir do modelo ISO/OSI (International Standards Organization/Open Systems Interconnection) que foi publicado em 1984 com o objetivo de criar um modelo de camadas que visava facilitar o desenvolvimento e a homogeneidade dos equipamentos e produtos de redes, dentre outros motivos. Apesar de podermos dizer que o modelo ISO/OSI é utilizado amplamente como diretriz para especificação e entendimento de elementos de rede, não podemos dizer que ele é um padrão de facto, com raras exceções, como, por exemplo, o protocolo IS-IS (Intermediate System to Intermediate System) que é um protocolo baseado puramente no padrão, mas que na prática é muito pouco disseminado. Dessa forma, apresentaremos as camadas desse modelo mais como uma referência que facilitará o entendimento dos princípios apresentados do que um modelo que seria implementado na prática nas diversas aplicações e tecnologias de redes. 82

83 Apesar de esse modelo ter uma aplicação prática restrita, o mesmo é muito didático e também se tornou um meio eficaz de tornar mais claro e homogêneo o discurso e o jargão utilizado pelos profissionais da área, por exemplo, quando usamos o termo switch camada 3 qualquer profissional em redes já saberá exatamente as várias características e particularidades desse equipamento sem necessitar-se qualquer explicação adicional. Segue uma explanação de cada uma das camadas do modelo ISO/OSI, fazendo uma comparação do mesmo com o protocolo TCP-IP (Transport Control Protocol Internet Protocol) que é um do modelo de facto e utilizado praticamente quase todas as comunicações de rede atualmente: Camada Física: Responsável pela transmissão de sinais digitais (bits) convertidos em sinais elétricos, óticos e mesmo ondas de rádio (wireless). Também responsável pela padronização de interfaces físicas, especificações elétricas, eletromagnéticas e óticas. Por exemplo, o foco de nosso trabalho será redes locais (LAN), utilizando cabeamento UTP (Unshielded Twisted Pair) com conectores RJ-45. Camada de Enlace: A camada de enlace trabalha com unidades de transmissão de dados chamadas de frames que usualmente são constituídos de algumas centenas ou mesmo alguns milhares de bytes, utilizando mecanismos de detecção e correção de erros, garantindo assim, um PDU (Protocol Data Unit) mais confiável e livre de erros para as camadas superiores. Na camada de enlace temos também o endereçamento físico dos elementos de rede, conhecido endereço MAC (Medium Access Control). Os PDU s são as unidades padrão de cada uma das camadas do modelo OSI. Camada de Rede Essa camada é responsável pelo encaminhamento lógico dos pacotes (o nome da PDU nessa camada), através do que chamamos rotas. Essas rotas podem ser estáticas, mantendo-se fixas mesmo com mudanças na rede ou dinâmicas que se adaptam às mudanças na rede através de protocolos de roteamento. Nessa camada também é tratado o endereçamento lógico dos elementos da rede, como por exemplo, o endereçamento IP. O endereçamento IP é uma notação constituída de quatro partes conhecidas como octetos e uma numeração complementar conhecida como máscara que determina as limitações lógicas desse endereço, por exemplo, quantos elementos podem ser endereçados pelo mesmo. 83

84 Essa camada abarca uma série de tecnologias, equipamentos e fundamentação teórica, podendo dizer que seria uma das mais relevantes camadas, especialmente quando falamos da função correspondente dessa camada no TCP-IP. Camada de Transporte A principal função da camada de transporte é receber os dados da Camada de Sessão, dividi-los em unidades menores, chamadas segmentos, se necessário, e entregá-los à camada de rede garantindo que os mesmos cheguem corretamente do outro lado da comunicação. A camada de transporte é também responsável pela multiplexação da comunicação entre os elementos da rede, permitindo que numa mesma conexão em nível de 3 (camada de rede) vários serviços possam comunicarem-se ao mesmo tempo. Em TCP-IP temos o conceito de comunicações orientadas à conexão e não orientadas a conexão, respectivamente conhecidas como TCP (Transport Control Protocol) e UDP (User Datagrama Protocol), a primeira garante o envio e o recebimento através de um sistema negociação, reconhecimento de chegada de segmentos e dispositivos de detecção e correção de erros, a segunda preocupada em apenas enviar os dados sem nenhuma garantia de chegada ao destino. A multiplexação é garantida no protocolo TCP-IP através de um dispositivo conhecido como porta, assim tem-se portas de serviços e aplicações já conhecidas como o HTTP, FTP e Telnet que possuem um número padrão, respectivamente portas 80, 21 e 23. Essas portas são conhecidas como well-known e ficam abaixo de número de porta Camada de Sessão Semelhante a camada de transporte a camada de sessão também gerencia a transmissão de dados, mas com algumas funções adicionais, através do estabelecimento de sessões entre os computadores. Um dos serviços da camada de sessão seria estabelecer um controle do diálogo entre as máquinas, por exemplo, se o tráfego fluirá nas duas ou numa mesma direção ao mesmo tempo dentro de determinada sessão. Uma sessão pressupõe uma conexão entre dois elementos por vez, por exemplo, para transferência de arquivos ou mesmo num sistema de acesso remoto com tempo compartilhado. A camada de sessão é também responsável por controle de operações dentro de determinados protocolos nos quais, por exemplo, não seria permitido os dois lados de a sessão realizarem uma operação ao mesmo tempo. Essa funcionalidade é conhecida como token management. 84

85 Ela é também responsável pelo serviço de sincronização, no sentido de estabelecer pontos de controle e recuperação durante a sessão, caso ocorra uma interrupção não programada da mesma. O protocolo TCP-IP não contempla formalmente uma camada de sessão, mas possui protocolos que utilizam os princípios da mesma, como por exemplo, o NFS (Network File System) dos sistemas operacionais Unix ou Linux. Camada de Apresentação A camada de apresentação preocupa-se com a sintaxe e semântica dos dados transmitidos. Além de serem agrupamentos de bits, os dados representam nomes, datas, valores financeiros, etc. Esses itens são convertidos em representações e estruturas de dados. Os computadores podem ter padrões diferentes de conversão, por exemplo, quando tratamos de representação de caracteres (letras e números em textos convencionais), os mesmos podem ser representados nos padrões ASCII, EBCDIC ou mesmo Unicode. Em suma a camada de apresentação recebe os dados vindos da rede e os representam da maneira que o computador que recebe esses dados, os compreenda. O protocolo TCP-IP não tem formalmente uma camada de apresentação. 85

86 Camada de Aplicação É importante ressaltar que quando abordamos o termo aplicação no modelo ISO/OSI estamos nos referindo a aplicações de redes. Essas aplicações são transferência de arquivo, correio eletrônico, emulação de terminal, navegador de Internet, etc. Novamente teremos na prática aplicações do protocolo TCP-IP como FTP (File Transfer Protocol), SMTP (Simple Mail Transfer Protocol), HTTP (HiperText Transfer Protocol), etc. Segue uma comparação entre o modelo ISO/OSI o protocolo TCP-IP: Figura 6 86

87 Processos e Threads Apesar de termos vistos processos e threads separadamente, quando os abordamos no monoprocessamento, para fins didáticos discutiremos os dois conceitos conjuntamente ao apresentarmos os fundamentos do processamento distribuído. Como vimos anteriormente, threads compartilham o mesmo espaço de memória que faz o seu comportamento e uso diferir significamente dos processos. Podemos dizer que os processos estão para os computadores, assim como as threads estão para os processos. Assim podemos ter um processo manipulando múltiplas threads. Essa característica faz as threads mais apropriadas para sistemas distribuídos por possuírem a funcionalidade intrínseca de paralelismo, podendo também utilizar primitivas blocking. Um exemplo de blocking seria quando uma thread ou mesmo um processo acessam o disco e precisam esperar a resposta do mesmo. Nesse momento eles entram num estado de blocking até receber os dados solicitados. Quanto o sistema está em blocking o processador fica inativo até receber a resposta do dispositivo que está executando a tarefa, nesse caso o disco e seu driver, perdendo assim em desempenho assim como em otimização de recursos computacionais. Existem sistemas ou primitivas non-blocking em que enquanto a tarefa de determinada chamada de sistema está utilizando outro dispositivo que não o processador, o mesmo é liberado para ser utilizado por outras threads ou processos. Primitivas non-blocking ou assíncronas como também são conhecidas, apesar de apresentarem a princípio uma melhor performance, possuem dificuldades significativas de controle e implementação. Assim falando-se na utilização de threads em ambientes distribuídos, o conjunto de múltiplas threads e primitivas blocking seria o mais recomendado, pois chamadas de sistema blocking ou síncronas torna a programação mais simples e múltiplas threads possibilitam o paralelismo. Seguem outros argumentos que fazem as threads mais apropriadas para o processamento distribuído: Iniciar e controlar uma thread para uma requisição entrante é muito menos onerosa para o sistema do que iniciar um processo. Quando temos múltiplas threads (Paralelismo) temos a possibilidade de multiprocessamento seja através de um processador multinúcleo, seja através de um computador com múltiplos processadores ou através de múltiplos computadores num ambiente de computação distribuída. 87

88 Por sua característica de paralelismo a implementação de threads possibilita a melhoria de desempenho nos sistemas. Programas com múltiplas threads tendem a ser menores e de mais fácil entendimento devido ao controle de fluxo simplificado. A maioria dos servidores demanda um alto uso de E/S, usando o sistema de bloqueio de chamadas (blocking) com as threads temos também uma simplificação dessa estrutura. RPC (Remote Procedure Call) e MPI (Message Passing Interface) Quando falamos em processamento distribuído, faz-se necessário uma exposição sobre o meio pelo qual as threads ou mesmo os processos se comunicam nesse tipo de ambiente. Enquanto sistemas monoprocessados utilizam funções como pipeline ou fork para promover a comunicação e a passagem de parâmetros entre processos ou threads, utilizando o barramento do computador e os componentes do processador para realizar essa tarefa, os sistemas distribuídos utilizam as redes como meio de comunicação entre os processos, necessitando de uma abordagem totalmente distinta para a comunicação entre processos e threads. Temos duas técnicas de comunicação interprocessos ou inter-threads 11, a primeira conhecida como Passagem de Mensagem (Message Passing) adotada para uso em sistemas de distribuídos no final da década de 70 e a Chamada Remota de Procedimento (Remote Procedure Call) sendo utilizada inicialmente em meados da década de 80. A Passagem de Mensagem é originalmente uma troca de mensagem unidirecional entre processos sendo visíveis ao programador, não possuindo a capacidade de responder diretamente a comandos executados num computador local por um computador remoto. Existem atualmente passagens de mensagem estruturadas que são bidirecionais. 11 Apesar do termo inter-thread ser utilizado quando abordamos a comunicação interprocessos, precisamos ter em mente que na maioria dos casos de computação distribuída teremos processos realizando a comunicação entre computadores distintos, processos esses que manipularão as threads localmente. Porém temos o cluster Kerrighed que se propõe a realizar a migração e comunicação de threads entre dois ou mais computadores. 88

89 Nesse contexto, uma mensagem é uma coleção de objetos de dados consistindo de um cabeçalho de tamanho fixo e um campo de payload de tamanho variável ou fixo, os quais podem ser gerenciados por um processo e entregues a seu destino. O tipo associado à mensagem provê uma informação estrutural sobre como a mensagem deve ser identificada. Uma mensagem pode ser de qualquer tamanho e pode conter dados ou ponteiros para dados fora da porção contígua da mensagem. Uma das portas TCP e UDP utilizadas pelo sistema de passagem de mensagem é a 3827, acima do range das portas well-known, conhecidas como registradas (registered) na nomenclatura do IANA (Internet Assigned Numbers Authority), órgão responsável pelo controle e registro das portas TCP e UDP a nível mundial, dentre outras atividades. A passagem de mensagens utiliza primitivas send e receive como mecanismos básicos para sua operação. Segue um diagrama no tempo que descreve a execução dessas primitivas: Figura 7 89

90 Podemos ter várias alternativas em virtude da semântica utilizada para as primitivas do modelo de Passagem de Mensagens: Portas de comunicação diretas ou indiretas; Primitivas blocking ou Non-blocking; Primitivas com ou sem buffers; Primitivas confiáveis ou não confiáveis; Formas estruturadas de Passagem de Mensagem baseada em primitivas; Abordando de modo sucinto essas variações de implementação de Passagem de Mensagem, quando falamos de portas de comunicação direta estamos falando em identificarmos diretamente o destinatário da mensagem ou a comunicação indireta que seria utilizar uma porta genérica para a qual a mensagem é enviada, sendo colocada em buffer e utilizada pelo processo que teria a necessidade da mesma. Os conceitos de primitivas blocking ou síncronas e non-blocking ou assíncronas já foram contemplados anteriormente. Falando de Passagem de Mensagem com ou sem buffer, seria a alternativa de buferizar ou não a mensagem, caso a primitiva receive não tiver sido ainda executada no destinatário quando o mesmo receber uma mensagem. Primitivas confiáveis e não confiáveis, diz respeito ao uso ou não de dispositivos de verificação de recebimento e retransmissão da mensagem caso a mesma tenha sido perdida. Primitivas não confiáveis não utilizam esse dispositivo, ao passo que primitivas as confiáveis garantem a entrega da mensagem. Esses mecanismos que determinam as primitivas confiáveis e não confiáveis estão relacionados com o protocolo de rede TCP-IP, que é utilizado usualmente na comunicação entre os computadores em sistemas distribuídos. As primitivas não confiáveis utilizariam conexões UDP e as confiáveis conexões TCP. Formas estruturadas de Passagem de Mensagem são alcançadas pela distinção de requisições e respostas, provida por um fluxo bidirecional de informações. 90

91 A RPC (Remote Procedure Call) é baseada no conceito fundamental de programação conhecido como chamada de procedimento. A conceituação mais geral do termo RPC seria um nível de linguagem de chamada num computador local ser automaticamente executada no mesmo nível de linguagem num computador remoto. A passagem da chamada é invisível ao programador, requerendo que o protocolo de transporte de rede suporte à transmissão dos argumentos e resultados das chamadas. Em termos de TCP-IP cada fabricante e desenvolvedor estabeleceu portas TCP e UDP para suas versões do RPC, por exemplo, a SUN utiliza as portas UDP e TCP 111 e a Encore as portas TCP e UDP 121. A ideia da RPC é muito simples e é baseada no modelo onde o cliente envia uma requisição e então entra em estado de blocking até o servidor remoto enviar uma resposta. Essa abordagem é muito similar aos mecanismos well-known e wellunderstood referidos como chamadas de procedimento também conhecidas como LPC (Local Procedure Call). Assim, o objetivo de uma Chamada Remota de Procedimento é permitir programas distribuídos serem escritos no mesmo estilo dos programas convencionais para sistemas computacionais centralizados. Isso implica que a RPC deve ser transparente, que é uma das principais vantagens dessa técnica de comunicação: o programador não precisa saber se o procedimento chamado está sendo executado num computador remoto ou local. Num sistema que suporta uma chamada de procedimento convencional, por exemplo, uma rotina de leitura de uma determinada biblioteca (biblioteca da RPC) é inserida trivialmente no programa. Esse procedimento, quando executado, primeiro coloca os parâmetros em registradores e depois assume o controle do kernel, tendo como resultado a execução de uma chamada de procedimento de leitura. Do ponto de vista do programador não há nada de especial nessa chamada de procedimento, basta inserir os parâmetros numa pilha (registradores) e executá-los. Num sistema que suporta RPC, a rotina de leitura é um procedimento remoto o qual será executado no servidor do outro lado da comunicação. Nesse caso, outra chamada de procedimento, chamada client stub, da biblioteca de RPC, é inserida no programa. Quando executada, ela também assume o controle do kernel. Entretanto, ao invés de colocar os parâmetros num registrador, ela os empacota numa mensagem e executa a primitiva de envio, a qual faz que o sistema operacional os envie para o servidor. Na sequência, ela chama a primitiva de recepção, entrando em blocking até ter de volta uma resposta. Já no servidor o sistema operacional repassa a mensagem que recebeu para um server stub, a qual é ligada ao servidor. 91

92 O stub entra em blocking waiting para mensagens, como resultado da execução da primitiva de recepção. Os parâmetros são desempacotados da mensagem recebida e um procedimento é chamado na forma convencional. Assim, os parâmetros e o endereço de retorno são colocados numa pilha, e o servidor não vê que a chamada original foi criada num cliente remoto. O servidor executa a chamada de procedimento e retorna os resultados para um solicitante virtual, o server stub. O stub empacota os resultados numa mensagem, executando uma primitiva de envio para retornar os resultados. O stub vai para o início do loop para executar a primitiva de recepção, e entra em blocking waiting para a próxima mensagem. A mensagem de resposta do servidor ao chegar ao cliente é copiada no buffer do procedimento client stub. A mensagem é desempacotada, os resultados extraídos e copiados no sistema do cliente na forma convencional. Como resultado da chamada de leitura, o processo do cliente obtém os dados disponíveis. O cliente desconhece que o procedimento foi realizado remotamente. Figura 8 92

93 Apesar de o foco nosso trabalho ser em clusters baseados em Kerrighed e o mesmo não utilizar RPC (Remote Procedure Call) para realizar a execução e migração de processos, entendemos que o conhecimento dessa técnica essencial do processamento distribuído irá nos ajudar a compreender melhor a técnica utilizada pelo Kerrighed para esse mesmo fim. Gerenciamento de Memória: Existem dois principais paradigmas no processamento distribuídos o primeiro é a execução de remota de processos seja através de MPI seja através de RPC e o segundo paradigma seria o compartilhamento de memória, que uma técnica de compartilhar as memórias de computadores distintos de modo que elas se comportem como uma memória convencional utilizada no monoprocessamento. Memória Compartilhada Distribuída: A DSM (Distributed Shared Memory) é uma abstração para compartilhar dados entre computadores que não utilizam uma mesma memória física. Os processos acessam a DSM, lendo e atualizando o que parece ser para eles uma memória convencional dentro do espaço de memória reservado para os mesmos, mas de fato, há sistemas subjacentes que garantem de modo transparente que as mudanças realizadas numa DSM sejam atualizadas em todos os computadores que compõe a mesma. Segue uma representação de uma memória compartilhada distribuída: Figura 9 A DSM poupa o uso de Passagem de Mensagens na programação de sistemas distribuídos em muitas situações, não sendo apropriada para modelos cliente-servidor que possuem uma característica intrínseca de requisição-resposta. 93

94 Comparando o uso de Passagem de Mensagens com DSM, enquanto na primeira as variáveis precisam ser estabelecidas num lado da comunicação, enviadas pela rede e reorganizadas no lado que as recebe, na segunda as variáveis são acessadas por ambos os computadores, não havendo a necessidade de uma transposição das mesmas. Em termos de sincronização enquanto no modelo de passagem de mensagens, a mesma é garantida através de primitivas que utilizam de técnicas como a implementação de lock server, no caso da DSM sincronização é assegurada através de desenvolvimento convencional em memória compartilhada tais como os semáforos. Devido a sua característica de persistência a DSM possui mais flexibilidade no concerne execução operações no tempo, por exemplo, um processo pode armazenar dados em certo espaço de memória que outro poderá acessar num período tempo à frente, diferentemente da passagem de mensagens em que a troca de dados precisa ser imediata devido ao processo de blocking utilizado nessa técnica. Em termos de eficiência sistemas baseados em DSM podem ser tão eficientes como os desenvolvidos com passagem de mensagem, pelo menos quando falamos numa quantidade pequena de computadores. Existem alguns aspectos da implementação de DSM que devem ser considerados: Estrutura: Nesse contexto, estrutura é a forma abstrata em que a DSM apresenta-se para as aplicações. Seguem algumas abordagens mais comuns de estrutura em DSM: Sem Estruturação: A maioria dos sistemas de DSM não estrutura seu espaço compartilhado de memória, sendo apenas um array linear de palavras. Estruturação através de tipo de dado: Nesse método a memória compartilhada é estruturada ou como uma coleção de objetos ou como uma coleção de variáveis de uma linguagem. Estruturação como banco de dados: Nesse caso a memória é estruturada como um banco de dados, sendo ordenada como uma memória associativa, isto é, um endereçamento de memória baseado, mas no conteúdo do que nomes ou endereços. 94

95 Sincronização: Como nos sistemas convencionais de memória compartilhada a sincronização também é necessária em DSM, utilizando os controles usuais como lock e semáforos. Esses dispositivos são aplicados através de passagem de mensagens. Consistência: DSM é um sistema de replicação de itens de dados compartilhados. Nesse sistema cópias desses itens compartilhados podem estar simultaneamente disponíveis nas memórias principais de vários computadores. Assim o desafio seria manter essas informações coerentes e idênticas em todos os nós que compõe o sistema distribuído. Para manutenção da consistência da DSM temos dois modelos principais de propagação de atualização ou replicação: write-update e write-invalidate. O primeiro que quando as atualizações são feitas localmente por um processo, é enviada uma réplica para todos os outros computadores que compõe o sistema através de multicast (comunicação TCP-IP de um para muitos, organizada em grupos), provocando assim a atualização da memória principal dos mesmos. O segundo, onde um item pode ser acessado como somente para leitura por um ou mais processos ou pode ser lido e escrito apenas por um único processo. Quando um processo que está compartilhando um item com outros, tenta escrever no mesmo, uma mensagem multicast é enviada para todos os processos que possuem uma cópia desse item, invalidando a mesma, recebendo uma confirmação dessa operação antes da escrita ser realizada. Além disso, qualquer processo que tenta acessar um item que está sendo atualizado é bloqueado. Abordamos até agora técnicas de replicação de atualizações em DSM visando evitar a inconsistência das informações na memória compartilhada existente em cada nó de um sistema distribuído. Veremos agora o principal modelo de consistência para garantir essa condição, que é o modelo de consistência sequencial. A ideia desse modelo é relativamente simples, não importa a ordem em que as operações de leitura e escrita são consideradas conquanto que seja a mesma para todos os processos. Uma memória consistentemente sequencial provê uma semântica de uma cópia/ a mesma cópia, pois todos os processos que compartilham um dado espaço de memória sempre veem exatamente o mesmo conteúdo armazenado nele. Essa seria a semântica mais intuitiva para lidar com esse tipo de necessidade de coerência de dados. 95

96 Dispositivos de Entrada/Saída: A forma mais usual de manipulação de dispositivos de entrada/saída em sistemas distribuídos seria através de sockets. O modelo de sistemas distribuídos que mais utiliza a API de sockets é o de cliente/servidor. Uma API (Application Programming Interface) é um conjunto de rotinas e padrões de uma determinada aplicação que são utilizados pelos sistemas e programas, de modo a poupar trabalho em desenvolvimento das funcionalidades realizadas por essa aplicação. Nesse caso, a API de sockets seja como integrante do sistema operacional, seja através de uma biblioteca, possibilita o acesso aos dispositivos de E/S em computadores remotos. Um socket é apenas uma abstração de E/S. A figura abaixo descreve o uso do mesmo num sistema cliente-servidor em ambiente UNIX, onde um processo do cliente requisita localmente uma conexão com um processo de um servidor remoto. Primeiro o servidor cria um socket e então escuta a requisição do cliente. Como o cliente já criou também um socket com o qual requisita a conexão com servidor, o mesmo aceitará a requisição e estabelecerá a conexão entre o servidor e o cliente. Figura 10 Criar um socket é muito semelhante a abrir um arquivo. Um programa pode ler e escrever dados de ou para um socket utilizando uma variável integer fd (file descriptor) da mesma forma que realizaria um processo de E/S para um arquivo. A diferença é que os dados são escritos por esse processo são enviados diretamente para um buffer do processo que tem o socket do outro lado da comunicação. Assim, uma conexão através de socket entre dois processo é como um pipe bidirecional. 96

97 Modelo do Socket O modelo do socket consiste em 3 partes: a camada de socket, a camada de protocolo e a camada de dispositivo. Esse modelo em camadas é designado para suportar as seguintes propriedades: Transparência: A comunicação entre dois processos não deve depender dos processos estarem ou não no mesmo computador. Eficiência: A aplicabilidade de qualquer comunicação interprocessos é limitada pelo seu desempenho. Compatibilidade: Processos já existentes que leem da entrada padrão de um arquivo e escrevem na saída padrão deve ser utilizável num ambiente distribuído sem mudanças. Arquivos: Um sistema distribuído de arquivos é um componente chave para qualquer sistema de computação distribuído. A principal função de um sistema de arquivos distribuído é criar um sistema arquivos comum que pode ser compartilhado por clientes sendo executados em computadores autônomos num sistema de computação distribuída. Esse sistema deve armazenar programas e dados, fazendo-os disponíveis quando necessário. Tendo em vista que esses arquivos podem estar armazenados em qualquer parte do sistema distribuído, isso significa que sistemas de arquivos distribuídos devem prover uma transparência da localização de arquivos. Isso significa que usuários, independente de sua localização física, podem acessar os arquivos sem saber em que computador os mesmos estão armazenados. Para atingir esse objetivo um sistema de arquivo distribuído usualmente utiliza o modelo cliente-servidor. Ele tipicamente provê dois tipos de serviços: serviço de arquivo e serviço de diretório, que são implementados por um servidor de arquivo e um servidor de diretório distribuídos entre os nós da rede. Esses dois servidores podem ser implantados como um único. 97

98 O sistema de arquivos distribuído mais utilizado em sistemas distribuídos é o PVFS (Parallel Virtual File System). A principal meta do PVFS é prover um acesso de alto desempenho a arquivos em aplicações de natureza paralela. O PVFS é implementado em nível de usuário, possuindo as seguintes características principais: Um consistente controle de nomes; Capacidade de distribuir dados entre os nós do sistema; Compatibilidade com os programas binários existentes; Como o PVFS é instalado em nível de usuário, não são necessárias alterações no núcleo do sistema operacional. Ele utiliza o TCP-IP para transmitir os dados sem dependência de passagem de mensagens. O PVFS consiste de três elementos: o processo (daemon) de gerenciamento que é executado num único nó, os processos de E/S que são executados em todos os nós que executam E/S e a biblioteca de aplicação através da qual as aplicações se comunicam com os processos do PVFS. O daemon de gerenciamento checa a permissão para as operações de criação, abertura, fechamento e remoção de arquivos. O daemon de E/S controla todas as operações de E/S sem a intervenção do gerenciador. Em termos de arquivos de dados, eles são armazenados localmente em cada nó de E/S. Os dados dos arquivos são distribuídos entre os nós de E/S, possuindo um único identificador para cada um dos arquivos como nos sistemas convencionais. O PVFS oferece suporte para os comandos de acesso, alteração e exclusão de arquivos dos sistemas operacionais convencionais. Uma alternativa de armazenagem de metadados, que no contexto de sistemas de arquivos paralelos, seriam as informações descrevendo as características dos arquivos, seria armazenar esses metadados num sistema arquivo NFS (Network File System) sistema de armazenamento distribuído de arquivos tradicional para sistemas Unix e Linux. 98

99 Chamadas de Sistema (System Calls) e Comunicação Interprocessos: Ao abordar processos e threads já vimos o meio pelo qual os sistemas distribuídos realizam chamadas de sistema, seja através de Passagem de Mensagem seja através de RPC que são responsáveis no contexto de processamento distribuído pela comunicação entre os processos. Para consolidar os conceitos apresentaremos uma implementação simples dos mesmos em código: Passagem de Mensagem (MPI): #include "mpi.h" int main( int argc, char **argv ) { char message[20]; int myrank; MPI_Status status; MPI_Init( &argc, &argv ); MPI_Comm_rank( MPI_COMM_WORLD, &myrank ); if (myrank == 0) /* código para o processo zero */ { strcpy(message,"hello, there"); MPI_Send(message, strlen(message)+1, MPI_CHAR, 1, 99, MPI_COMM_WORLD); } else if (myrank == 1) /* código para o processo 1 */ { MPI_Recv(message, 20, MPI_CHAR, 0, 99, MPI_COMM_WORLD, &status); 99

100 printf("received :%s:\n", message); } MPI_Finalize(); } Nesse exemplo, o processo zero (myrank = 0) envia uma mensagem para processar a operação de envio MPI_SEND. A operação especifica um buffer de envio na memória do remetente da mensagem do qual os dados da mensagem são retirados. No exemplo acima, o buffer de envio consiste de um armazenamento contendo a variável message na memória do processo zero. A localização, o tamanho e o tipo do buffer de envio são especificados pelos primeiros três parâmetros da operação de envio. A mensagem enviada ocupará 13 caracteres dessa variável. Em adição, a operação de envio associa um envelope à mensagem. Esse envelope especifica o destino da mensagem e contém informação que pode ser utilizada para a operação de recepção conseguir selecionar uma mensagem em particular. Os últimos três parâmetros da operação de envio juntamente com o rank do remetente, especificam o envelope para a mensagem enviada. O processo um (myrank=1) recebe essa mensagem com a operação de recepção MPI_RECV. A mensagem a ser recebida é selecionada de acordo com o valor do seu envelope e os dados da mensagem são armazenados no buffer de recepção. Nesse exemplo, o buffer de recepção consiste de um armazenamento contendo a string message na memória do processo um. Os primeiros três parâmetros da operação de recepção são usados para especificar a localização, o tamanho e o tipo do buffer de recepção. Os próximos três parâmetros são utilizados para selecionar a mensagem entrante. O último parâmetro é usado para informação de retorno sobre a mensagem recebida. 100

101 RPC: Segue uma aplicação standalone que será convertida num RPC (Esse exemplo de RPC é desenvolvido em ambiente Windows): // Arquivo Standalone.cpp #include <iostream> // Função futura do Servidor. void Output(const char* szoutput) { std::count << szoutput << std::endl; } int main() { // Chamada futura do cliente Output ("Hello Lonely World!"); } Agora temos o código para a geração do IDL (Interface Definition Language) que é uma linguagem para definição de interfaces. Podemos comparar a IDL como um cabeçalho de um programa em C com mais funcionalidades: 101

102 // Arquivo Example1.idl [ // Um identificador único que distingue essa // interface das outras. uuid( eaf3-4a7a-a0f2-bce4c30da77e), // Essa é a versão 1.0 dessa interface. version(1.0), // Essa interface será usada como um suporte para // ligação implícita chamada hexample1binding. implicit_handle(handle_t hexample1binding) ] interface Example1 // A Interface é chamada Example1 { // Uma função que toma uma string terminada em zero. void Output( [in, string] const char* szoutput); } Para usar o IDL numa aplicação nós precisamos processá-lo através de programas, como por exemplo, o midl.exe que traduzirá o IDL para um client stub e um server stub que serão compilados posteriormente por um compilador C. 102

103 Figura 11 O próximo passo seria gerar os arquivos e colocá-los em uso na aplicação de servidor. // Arquivo Example1Server.cpp #include <iostream> #include "Example1.h" // Função de Servidor. void Output(const char* szoutput) { std::count << szoutput << std::endl; } int main() { RPC_STATUS status; // Usa o protocolo combinado com o endpoint para receber // remote procedure calls (RPC). status = RpcServerUseProtseqEp( reinterpret_cast<unsigned char*>("ncacn_ip_tcp"), // Uso do protocolo TCP/IP 103

104 RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Fila de tamanho do backlog para TCP/IP. reinterpret_cast<unsigned char*>("4747"), // Porta TCP utilizada. NULL); // Sem segurança. if (status) exit(status); // Registra a interface do Example1. status = RpcServerRegisterIf( Example1_v1_0_s_ifspec, // Interface to register. NULL, // Usa o vetor entry point gerado pelo MIDL. NULL); // Usa o vetor entry point gerado pelo MIDL. if (status) exit(status); // Começa a ouvir por RPC s em todas as interfaces registradas // Essa chamada não será retornada até que o // RpcMgmtStopServerListening seja chamado. status = RpcServerListen( 1, // Número mínimo de threads recomendado. RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Número //máximo de threads recomendado. FALSE); // Passa a efetivamente a ouvir por RPC s nesse momento. if (status) exit(status); 104

105 } // Função de alocação de Memória para o RPC. // O runtime usa essas duas funções para alocar/liberar // a memória suficiente para passar a string para o servidor. void* RPC_USER midl_user_allocate(size_t size) { return malloc(size); } // Memory deallocation function for RPC. void RPC_USER midl_user_free(void* p) { free(p); } Esse código apesar de diferente da aplicação standalone, possui significativa semelhança a um processo sendo executado num mesmo computador. Existem alguns códigos de inicialização para registrar a interface, mas a função de saída permanece a mesma. Segue a aplicação cliente que conectará com o servidor: // Arquivo Example1Client.cpp #include <iostream> #include "Example1.h" int main() { RPC_STATUS status; 105

106 unsigned char* szstringbinding = NULL; // Cria-se uma string de manipulação de ligação. // Essa função nada mais é do que um printf. // A conexão não está ainda estabelecida. status = RpcStringBindingCompose( NULL, // UUID to bind to. reinterpret_cast<unsigned char*>("ncacn_ip_tcp"), // Uso do protocolo // TCP-IP. reinterpret_cast<unsigned char*>("localhost"), // Uso de endereço IP reinterpret_cast<unsigned char*>("4747"), // Uso da porta TCP. NULL, // O Protocolo depende da opção de rede utilizada. &szstringbinding); // String de ligação de saída. if (status) exit(status); // Valida o formato da string manipulação de ligação e a converte // para uma manipulação de ligação. // A conexão ainda não está estabelecida. status = RpcBindingFromStringBinding( szstringbinding, // A string de ligação a ser validade. &hexample1binding); // Coloca o resultado numa manipulação // implícita de ligação definida no arquivo IDL. if (status) exit(status); 106

107 RpcTryExcept { // Chama a função RPC. A manipulação de ligação hexample1binding // é usada implicitamente. // A conexão é realizada nesse momento. Output("Hello RPC World!"); } RpcExcept(1) { std::cerr << "Runtime reported exception " << RpcExceptionCode() << std::endl; } RpcEndExcept // Libera a memória alocada pela string. status = RpcStringFree( &szstringbinding); // String a ser liberada. if (status) exit(status); // Libera os recursos de manipulação de ligação e desconecta-se do servidor. status = RpcBindingFree( &hexample1binding); // Libera a manipulação implícita de ligação definida no // arquivo IDL. if (status) 107

108 exit(status); } // Função de alocação de memória para o RPC. // O runtime usa essas duas funções para alocação/liberação // de memória suficiente para passar a string para o servidor. void* RPC_USER midl_user_allocate(size_t size) { return malloc(size); } // Função de liberação da memória para o RPC. void RPC_USER midl_user_free(void* p) { free(p); } Resumindo, primeiro necessita-se processar o arquivo IDL para obter-se o client stub, o server stub e o arquivo comum de cabeçalho. O client stub e o server stub são compilados, como uma implementação de cliente e servidor. Faz-se o linkedit das duas aplicações, executando as mesmas. 108

109 Figura 12 Tratando-se de plataforma Linux existem algumas variações de implementação. A padronização do formato dos dados que no ambiente Windows é realizada através do código IDL, no ambiente Linux utiliza-se o padrão XDR (External Data Representation Standard) definido na RFC O objetivo dessa linguagem é garantir a portabilidade do RPC em arquiteturas diversas. Segue uma especificação básica do XDR: program NOMEDOPROGRAMA { version NOMEDAVERSAO { TIPO NOMEDOPROCEDIMENTO (TIPO ARGUMENTO) = X; } = Y; } = ; TIPO = NOME; As palavras program e version não podem ser usadas para identificar os programas e procedimentos. 109

110 Seguido da palavra program deverá conter o nome do programa, que irá agrupar uma ou mais versões de um ou mais procedimentos. Seguido da palavra version deverá constar o nome da versão de um ou mais procedimentos. O nome de uma versão não pode ocorrer mais de uma vez no mesmo escopo de definição de um programa. O nome de um procedimento não pode ocorrer mais de uma vez numa mesma versão. Os identificadores dos programas ficam no mesmo espaço de endereçamento das definições dos tipos de dados e constantes utilizadas. Por convenção os nomes de programa, versão e procedimento deverão ser escritos em letras maiúsculas. X é um número inteiro positivo que identifica o número de um procedimento. Y é um número inteiro positivo que identifica o número da versão do conjunto de procedimentos. TIPO é um tipo de dado que um procedimento poderá retornar ou receber como argumento. Poderá ser: int, char, string, void, enum, bolean, float, double e structure. ARGUMENTO é o nome do argumento que o procedimento irá receber. Ele deverá ser de um TIPO específico. 110

111 define o número do programa. Este número deverá ser escrito na forma hexadecimal, de acordo com os ranges abaixo: fffffff definido pelo rpc@sun.com ffffff definido pelo usuário fffffff transiente fffffff reservado fffffff reservado a bfffffff c dfffffff e ffffffff reservado reservado reservado O primeiro grupo de números é administrado pela SUN MICROSYSTEMS e padronizado em todos os sistemas. O segundo grupo poderá ser usado por alguma aplicação específica. Se uma aplicação RPC desenvolvida for de interesse geral, poderá requerer um número do primeiro grupo. O terceiro grupo é utilizado pelas aplicações que criam números dinamicamente. Os demais grupos são reservados para uso futuro. Segue um exemplo simples protocolo utilizando a definição XDR: program PROGRAMAPING { /ÚLTIMA VERSÃO DO PROGRAMA EM TESTE version PING_ULTIMAVERSAO { void PING_PROCEDIMENTO_NULL(void) = 0; int PING_PROCEDIMENTO_BACK(int NUM) = 1; } = 2; /VERSÃO ORIGINAL EM PRODUÇÃO Version PING_VERSAOORIGINAL { 111

112 void PING_PROCEDIMENTO_NULL(void) = 0; } = 1; } = Nesse exemplo a definição estabelece duas versões distintas de procedimentos. Versão 2 para PING_ULTIMAVERSAO e versão 1 para PING_VERSAOORIGINAL. A versão PING_ULTIMAVERSAO possui dois procedimentos e a versão PING_VERSAOORIGINAL apenas um. O programa PROGRAMAPING tem como identificação o número Por convenção, o protocolo deve ser salvo com a extensão x. Esse programa pode ser compilado pelo programa rpcgen que está disponível no pacote de compiladores GLIBC. Como a definição IDL do Windows ele gerará os seguintes códigos em linguagem C: Um arquivo de cabeçalho com as definições comuns ao servidor e cliente. Um conjunto de rotinas XDR que traduzem os tipos definidos no arquivo de cabeçalho. Um programa base com as chamadas RPC para os servidores. Um programa base com as chamadas RPC para o cliente. Considerando que salvamos o código acima como ping.x, o rpcgen gerará os seguintes arquivos: ping.h Cabeçalho com definições comuns ao servidor e cliente. ping_clnt.c Programa base com as chamadas de RPC para o cliente. ping_svc.c Programa base com as chamadas de RPC para o servidor. ping_xdr.c Filtros XDR para comunicação entre arquiteturas diferentes. 112

113 Dificuldades na manipulação de processos num ambiente de processamento distribuído Race Message Considerando um ambiente utilizando DSM (Distributed Shared Memory) podemos dizer que os desafios decorrentes de uma corrida (race) de processos são muito semelhantes aos enfrentados na computação monoprocessada, pois essa condição está relacionada ao compartilhamento de memória. Temos, porém, há outro tipo de race que ocorre em sistemas distribuídos que utilizam passagem de mensagem, quando muitas requisições conflitantes de clientes competem para acessar o mesmo servidor. Podemos ilustrar messages races através do diagrama abaixo. Considere três processos P1, P2 e P3. Evento a: P1 envia Mensagem 1 para P2 Evento b: P2 recebe a mensagem Evento c: P3 envia Mensagem 2 para P2 Evento d: P2 recebe a mensagem No diagrama abaixo as linhas verticais representam processos assíncronos. As mensagens trocadas entre os processos são representadas pelas flechas. O lado não pontiagudo da seta representa o envio da mensagem. O lado pontiagudo representa o recebimento da mensagem. 113

114 P1 P2 P3 a Mensagem 1 Mensagem 2 c b d Figura 13 Devido a não previsibilidade em certos escalonamentos de processos e atrasos em mensagens, a ordem em que as mesmas são recebidas é incerta. Por exemplo, a Mensagem 1 pode ter algum atraso, desse modo a Mensagem 2 pode ser recebida primeiro. Esse não determinismo causa um problema, mesmo executando o sistema com a mesma entrada não é garantida a reprodução da execução original. Seguem algumas características de uma message race: O efeito sobre o controle de fluxo do sistema. Uma message race pode causar que um sistema tome um caminho de execução diferente, dependendo como o mesmo é tratado. A severidade da corrida. Uma corrida benigna não causa efeito externo nos resultados do sistema. Uma corrida crítica afeta o resultado do sistema. Uma abordagem para detectar e minimizar os efeitos de race message é de natureza preventiva, isto é, ferramentas de testes e monitoramento que verificam a ocorrência desse tipo de evento, antes que o sistema distribuído seja liberado para operação. Basicamente esses sistemas executam rotinas de troca de mensagem repetidamente para verificar se os resultados são os mesmos. Caso os resultados sejam diferentes temos um indício de uma race condition crítica. Uma dessas ferramentas é a TMT (Testing and Monitoring Tool) para sistemas distribuídos desenvolvida pela Siemens AG da Alemanha. 114

115 Temos também o MPIRace-Check (PARK, 2007) desenvolvido por pesquisadores das Universidades de Chonnam e Gyeongsang. Deadlocks em Sistemas Distribuídos Deadlocks em sistemas distribuídos são similares a deadlocks em sistemas monoprocessados, sendo usualmente de solução mais onerosa, por serem mais difíceis de serem evitados, detectados ou de terem uma prevenção efetiva, devido aos dados estarem espalhados entre vários processos e computadores. As quatro principais estratégias para manipular dealocks em sistemas distribuídos são: Indiferença: Ignora-se o problema de deadlock. Detecção: Permite a ocorrência de deadlocks, os detecta, tentando recuperar os processos. Prevenção: Torna estatisticamente os deadlocks impossíveis em termos estruturais. Evitação: Evita os deadlocks por alocar os recursos com cuidado. A indiferença à ocorrência de deadlocks é popular tanto em sistemas monoprocessados como em sistemas distribuídos, muitas vezes deixando a atividade de manipular os deadlocks para as próprias aplicações como, por exemplo, um banco de dados. A técnica de detecção e recuperação é popular porque a prevenção e a evitação são de difícil implementação. A prevenção de deadlocks é possível devido à existência de transações atômicas, que é técnica de voltar as transações para suas condições iniciais caso ocorra alguma indisponibilidade durante a execução das mesmas. A evitação de deadlocks é usada raramente pela dificuldade de saber-se a priori o quanto de recurso cada processo precisará numa dada transação. Como a prevenção e evitação são de difícil implementação, a técnica mais explorada na prática seria a detecção, tendo como principal recurso as transações atômicas. 115

116 A detecção de deadlocks utiliza uma técnica conhecida como WFG (Wait-For-Graph), onde os processos são modelados em termos de grafos, estabelecendo que um nó representa um processo, um arco representa um processo que está esperando por outro que mantém um recurso que ele deseja e um círculo que representa um deadlock. Quando tratamos de detecção de deadlocks em sistemas distribuídos, uma das técnicas utilizada seria a detecção centralizada de deadlocks que de certa forma segue a mesma linha de raciocínio utilizada nos sistemas monoprocessados. Nessa técnica cada computador mantém um grafo de recursos próprios e o coordenador mantém um grafo de recursos para todo o sistema. O coordenador detecta um círculo, cancelando (kill) um dos processos para interromper o deadlock. Para que o coordenador mantenha um grafo de recursos do sistema global, um sistema de mensagens é utilizado. Em termos de algoritmos que tratam as abordagens para resolução do problema de deadlock, temos os algoritmos de detenção de Chandy-Misra-Haas (CHANDY, 1983) que permite que um processo possa esperar por mais de um recurso ao mesmo momento, havendo um sistema de troca de mensagens para verificar a existência de círculos e consequentemente deadlocks. Para prevenção temos os algoritmos Wait-die e Wound-wait, que trabalham com timestamp (tempo em que o processo começa a utilizar o recurso), tendo cada algoritmo uma abordagem e estratégias diferentes ao utilizarem essas informações. Para a evitação temos o algoritmo do banqueiro desenvolvido por Edsger Dijkstra (DIJKSTRA, 1977) que trabalha com uma previsão e controle dos recursos dos processos manipulados pelo mesmo. 116

117 O Problema do Drink dos Filósofos Ao abordar a questão de alocação de recursos em sistemas monoprocessados apresentamos alguns problemas clássicos para abordagem desse aspecto da computação, dentre eles o Jantar dos Filósofos. Temos uma variação desse problema aplicada para computação distribuída conhecida como o Drink dos Filósofos em que uma das soluções proposta por K. M. Chandy 12 (CHANDY, 1984) e J. Misra 13 (MISRA, 1984), utiliza a abordagem de favorecer um dos processos em detrimento dos outros numa situação de conflito entre os mesmos. Esse problema é uma generalização do problema do Jantar dos Filósofos que como vimos, trabalha com a questão da sincronização, que já abordamos nesse trabalho. Nesse caso, os processos são os filósofos, localizado nos vértices do grafo G. Um filósofo pode estar em um de três estados: (1) Tranquilo (2) Sedento (3) Bebendo. Os lados do triângulo seriam as garrafas de bebida. Um filósofo pode beber somente de garrafas (lados) que formam o seu vértice. Um filósofo tranquilo pode tornar-se sedento. Um filósofo sedento precisa de garrafas cheias para ele saciar a sua sede. Ele pode necessitar de uma quantidade diferente de garrafas em diferentes rodadas de bebida. Ao manter e tomar todas as garrafas que o filósofo se apropria, ele entra num estado de filósofo bebendo, mantendo-se nesse estado até tomar toda bebida que necessita, retornando ao estado de filósofo tranquilo após um tempo finito. O processo favorecido deve ter alguma propriedade que o distinga dos outros. Para garantir certa justiça nessa escolha, a propriedade que distingue o processo escolhido não é sempre a mesma. Uma implementação distribuída de um grafo de precedência acíclica, onde a profundidade do processo (a mais longa cadeia de predecessores) seria uma das propriedades distintivas, podendo garantir a rotatividade da escolha do processo favorecido. Uma simples regra de resolução de conflito associada a um grafo acíclico garante uma resolução justa para todas as situações dessa natureza segundo os autores. 12 Kanianthra Mani Chandy é professor de Ciência da Computação no California Institute of Technology. Ele foi o Chefe Executivo do departamento por duas vezes e também professor na Caltech desde Jayadev Misra detém a cadeira Schlumberger Centennial em Ciência da Computação, sendo também professor dessa disciplina. 117

118 Para entender o problema do Drink dos Filósofos, precisamos compreender alguns conceitos de modelos de grafos de conflito. Um sistema distribuído é representado pelo grafo G com uma correspondência um para um entre os vértices (p, q e r) que correspondem a processos. Esse modelo não considera a precedência dos processos em caso de conflito, não havendo uma distinção entre eles. No modelo H existe uma precedência entre os processos indicada pelas setas. Grafo G Grafo H Figura 14 A título de ilustração no caso do grafo H, p, q e r teriam como profundidade no que se refere a predecessores em relação a r, respectivamente 0, 1 e 2. Para garantir a justiça na escolha dos processos que por ventura entrarem em conflito considerando o grafo H, é necessário, nesse caso, uma mudança de quantidade de predecessores dos processos participantes dos conflitos. Com essas informações preliminares podemos agora abordar o problema do Drink dos Filósofos com mais propriedade. Um filósofo pode estar num estado tranquilo por um período de tempo arbitrário. Dois filósofos são vizinhos se e somente se houver um lado entre eles no grafo G. Os vizinhos podem enviar mensagens um para o outro. As mensagens são entregues num tempo arbitrário, mas finito. Os recursos, tal como as garrafas, são codificados e transmitidos como mensagens. O problema é resolvido através de uma solução não probabilística que satisfaça as seguintes condições: Justiça. Nenhum filósofo fica sedento para sempre. 118

119 Simetria. Todos os filósofos obedecem precisamente todas as regras para adquirir ou liberar garrafas. Não há prioridade ou qualquer outra forma de aquisição parcial externamente especificada entre filósofos e garrafas. Economia. O Filósofo envia e recebe um número finito de mensagens entre as transições de estado. Em particular, um filósofo tranquilo não envia nem recebe um número infinito de mensagens. Concorrência. A solução não nega a possibilidade de beber-se simultaneamente de diferentes garrafas por diferentes filósofos. Ligação. Um número de mensagens em trânsito, a qualquer momento, entre qualquer par de filósofos é uma ligação. Além disso, o tamanho da mensagem também é considerado uma ligação. O problema dos Filósofos Bebendo é um paradigma geral para modelar conflitos entre processos. Filósofos vizinhos serão impedidos de beber simultaneamente se eles desejarem beber da mesma garrafa esse é um modelo de situação conflito para acesso exclusivo para arquivos comum. Filósofos vizinhos podem beber simultaneamente de garrafas diferentes esse é um modelo de situação para processos de gravação em diferentes arquivos. Deve-se prevenir o sistema de entrar em estados em que filósofos vizinhos são indistinguíveis. Por exemplo, considere filósofos organizados num anel e o estado de cada filósofo é de beber de sua garrafa à esquerda filósofos não possuem uma característica que possa distingui-los. Se todos os filósofos estiverem bebendo de suas bebidas à esquerda e então requererem as duas garrafas para próxima rodada, então os filósofos permanecerão sedentos para sempre porque um algoritmo determinístico não pode escolher entre filósofos indistinguíveis. Entretanto, um estado do sistema certamente possível seria quando todos os filósofos mantém sua garrafa à esquerda. Se esse estado for proibido, estaríamos proibindo um estado viável com o qual estaríamos obtendo algum sucesso, simplesmente para resolver um único problema, proibir que um estado que viável viole a condição de Concorrência. Parece estarmos num dilema, pois as condições de processos simétricos, soluções não probabilísticas e concorrência são incompatíveis nesse problema. A solução seria implementar grafo de precedência H utilizando recursos auxiliares especiais. 119

120 O grafo H é sempre acíclico. A profundidade do processo é sua característica de distinção em relação aos outros. O grafo é implementado utilizando a mesma abordagem dos garfos do problema do Jantar dos Filósofos. Dois processos compartilham um grafo se existe a possibilidade de conflito entre eles. A regra para resolução do conflito seria: um processo u cede num conflito com um processo v se e somente se u não manter o garfo compartilhado com v. O algoritmo garante que se os processos v e u estão em conflito e u tiver precedência sobre v no grafo de precedência, então a resolução do conflito eventualmente resolverá o conflito em favor de u. Essa mesma abordagem é utilizada na resolução problema dos Drink dos Filósofos. 120

121 Escalonamento de processos em sistemas distribuídos As técnicas de escalonamento usadas pelos sistemas operacionais em geral são baseadas em sua grande parte na premissa que os processos são independentes. Assume-se que as interações entre os processos são mais exceções do que a regra. Porém tratando-se de sistemas distribuídos a independência dos processos torna-se não válida com o passar do tempo. Em sistemas multiprocessados, dentre eles os sistemas distribuídos, tem-se sido encorajado um tipo de programação onde coleções de processos cooperativos usam muitos processadores concorrentemente para realizar tarefas. Grupo de processos é utilizado mesmo no monoprocessamento, por exemplo, no mecanismo de pipeline do Unix/Linux. Assim podemos assumir que os processos seriam criados em grupos e que a comunicação intragrupo seria muito mais frequente que a comunicação intergrupo. Podemos também considerar que um número significativo de processadores estará disponível para tratar esses grupos de processos e que cada processador utilizará o mecanismo de executar múltiplas instruções num mesmo ciclo de clock conhecido como multiprogamação N-way. Figura

122 John K Ousterhout 14 (OUSTERHOUT, 1982) propôs alguns algoritmos para tratar o escalonamento em sistemas distribuídos dentro do conceito que ele chamou coscheduling. Esse algoritmo considera os padrões de comunicação interprocessos enquanto estabelece um escalonamento para garantir que todos os membros do grupo sejam executados ao mesmo tempo, como podemos ver na matriz representada pela Figura 15. Dessa forma, a coluna 4 consiste de todos os processos executados no processador 4. A linha 3 é a coleção de todos os processos que são executados no time slot 3 de um dos oito processadores, iniciando com o processo do processador número 0. O essencial dessa ideia é ter cada processador utilizando um algoritmo de escalonamento round robin, que seria um escalonamento sequencial sem retornar ao início da sequencia ao final da varredura, tendo todos os processadores executando os processos no slot 0 num período fixo, então tendo todos os processadores executando os processos no slot 1, assim por diante. Uma mensagem TCP-IP pode ser utilizada para informar para cada processador quando uma troca de processo ocorre, para manter a sincronização dos time-slots. Assim, a melhor maneira de utilizar esse algoritmo ao manipular grupo de processos, seria colocar todos num mesmo time slot, para que sejam executados simultaneamente, maximizando os recursos de comunicação interprocessos. Existem variações desse modelo visando uma melhoria de desempenho, por exemplo, podemos separar as linhas da matriz e concatená-las de modo a criar uma única longa linha. Nesse modelo um grupo de processos é colocado nessa tabela contínua, a fim de ter cada processo do grupo alocado a um processador. Caso, num primeiro momento, isso não for possível, o grupo é deslocado para uma nova janela da esquerda para a direita até encontrar uma sequencia de processadores livres que atendam a necessidade desse grupo. O escalonamento utiliza o mesmo método de estabelecer-se uma janela que irá mover-se da esquerda para direita até que todos os processos sejam executados, quando isso ocorre, retorna-se para o lado esquerdo da tabela e inicia-se uma nova varredura para um novo grupo de processos. 14 John K. Ousterhout é professor e pesquisador do departamento de Ciência da Computação na Universidade de Stanford. Ele é também presidente da Electric Cloud, Inc. Ele é provavelmente mais conhecido como o criador da linguagem de script Tcl. Obteve Mestrado em Física na Universidade de Yale e doutorado em Ciência da Computação na Universidade Carnegie Mellon. 122

123 Escalonamento em sistemas em tempo real em computação distribuída Comparado ao escalonamento em sistemas em tempo real em computação monoprocessada, o escalonamento de tarefas em tempo real em ambiente distribuído é de implementação consideravelmente mais complexa. Temos visto que escalonamento para sistemas monoprocessados, executando tarefas em tempo real, possui uma complexidade polinomial (Complexidade P). Entretanto, para determinar um sistema ótimo para tarefas em tempo real para sistemas distribuídos necessitamos de resolver problemas de complexidade NP (Nondeterministic Polynomial Time). O escalonamento em sistemas distribuídos consiste em dois subproblemas: alocação de tarefas aos processadores e escalonamento de tarefas em processadores individuais. O problema de designação de tarefa refere-se como particionar um grupo de tarefas e então designá-las aos processadores. Essa designação pode ser estática ou dinâmica. Enquanto que a designação estática é permanente, a dinâmica é variável e as tarefas são designadas aos nós na medida em que surgem, podendo ter diferentes instâncias de uma tarefa alocadas em diferentes nós. Depois que as tarefas são alocadas aos diferentes processadores, a dinâmica passa ser semelhante ao escalonamento em ambientes monoprocessados, tendo cada nó do sistema distribuído tratando dos processos a ele designado. Por suas características usualmente complexa, o escalonamento em tempo real em sistemas distribuídos é alcançado através de algoritmos heurísticos. Um aspecto crítico nos sistemas distribuídos em tempo real é a temporização (clock). Além do uso tradicional do clock nos sistemas operacionais, nos sistemas distribuídos o mesmo é utilizado para timeout e timestamping. O timeout tem como função principal determinar a falha na execução de uma tarefa após um tempo pré-determinado. Timestamping é utilizado para informar na própria mensagem o tempo no qual a mesma saiu de sua origem, para fins de reconhecimento da idade das mensagens e assim como a ordenação das mesmas. Problemas de sincronização são especialmente críticos em sistemas distribuídos por comprometerem a troca de mensagens que são o meio de comunicação entre processos nessa modalidade de processamento. 123

124 Aplicações Multimídia em Sistemas Distribuídos Os sistemas multimídia representam uma classe especial de sistemas complexos de computação. Como tal, seus projetos devem partir da premissa que necessitarão considerar como característica principal uma quantidade imensa de dados que precisam ser processados e transmitidos de maneira contínua, cumprindo as exigências relativas a sincronização a fim de ter mensagens íntegras recebidas pelo usuário final. Outro aspecto essencial é a qualidade de serviço (QoS) que compreende itens como reserva de banda, latência, jitter, etc. Nos sistemas multimídia, os requerimentos de QoS variam consideravelmente de uma mídia para outra, por exemplo, fluxos de vídeos requerem uma vazão consistentemente alta, mas tem certa tolerância para certos níveis de jitter e erros de pacotes. Em contraste, as aplicações de áudio manipulam um volume muito menor de dados (portanto, não requerendo alta largura de banda), porém são mais sensíveis a jitter e taxa de erros. Fluxos de mídia contínua têm duas propriedades importantes. A primeira seria sua fidelidade usualmente dependente da sequencia temporal dos dados. Essa propriedade temporal de mídias contínuas impõe requerimentos que faz com que os códigos que manipulam fluxos de mídia necessitem ser escalonados dentro de janelas de tempo aceitáveis. A segunda propriedade seria que eles são normalmente tolerantes à perda de conteúdo da informação, particularmente se conhecemos a característica da informação (por exemplo, muitos modelos de compressão são estabelecidos baseados na percepção humana de sons e imagens para alcançar maiores taxas de compressão). Podemos dizer que em contraste a aplicações convencionais, aplicações multimídias são sensíveis a variações de tempo e não tanto exigentes à perda de parte das informações. Devido a isso os protocolos de transporte de voz e vídeo utilizam normalmente pacotes UDP, como por exemplo, o RTP (Real Time Protocol). Abordando o aspecto de redes, segue uma descrição dos principais protocolos que tratam de comunicação de sistemas multimídia, dando suporte aos processos de transmissão, recepção e execução de aplicações multimídias. 124

125 RTP (Real Time Protocol): O transporte de fluxos de mídia nas diversas aplicações, é na maioria dos casos implementado com RTP, o qual é protocolo baseado em IP para transmissão de dados e voz. Ele é um protocolo leve sem controle de erro e de fluxo, QoS e reserva de recurso. Para garantir sincronismo e a ordenação dos pacotes, o RTP provê dispositivos como timestamping, sequenciamento, dentre outros. Timestamping é a uma das mais importantes informações para aplicações em tempo real. O remetente informa tempo quando pacote é processado. O destinatário usa o time stand para reconstruir a temporização original. O RTP não é por si mesmo responsável pelo sincronismo, essa função é feita no nível de aplicação. Os números de sequencia são utilizados para determinar a ordem correta, pois o UDP não tem apenas essa funcionalidade. O sequenciamento também é utilizado para detecção de perda de pacotes. O identificador de payload especifica o formato do mesmo assim como a codificação e compressão. Utilizando esse identificador, a aplicação sabe como interpretar e executar os dados do payload. Exemplos de especificações seriam PCM, MPEG1 / MPEG2, etc. A identificação da origem permite que no recebimento do pacote a aplicação saiba de onde os mesmos estão vindo. Por exemplo, numa áudio-conferência, pelo identificador da origem é possível saber quem está entrando na mesma. RTCP (RTP Control Protocol): Protocolo de controle designado para trabalhar em conjunção com o RTP. Durante uma sessão RTP, os participantes periodicamente trocam pacotes RTCP para transmitir informações sobre a qualidade da entrega dos dados e de participação em sessões. 125

126 RTSP (Real Time Streaming Protocol): O RTSP é um protocolo de apresentação cliente-servidor para habilitar a entrega controlada de fluxos de multimídia em redes IP. O RTSP provê métodos para executar comandos tais como play, fast-forward, fast-rewind, pause e stop, similar as funcionalidades oferecidas por aparelhos de CD e DVD. Ele é um protocolo em nível de aplicação designado para trabalhar com os protocolos de nível mais baixo como RTP e o RSVP (Resource Reservation Protocol), agindo como um controle remoto para servidores de multimídia, utilizando TCP ou UDP. O RTSP pode ter um ou vários fluxos de mídia contínuos. RSVP (Resource Reservation Protocol) O RSVP é um protocolo de controle que permite um usuário do recurso multimídia requisitar uma qualidade de serviço fim a fim para o seu fluxo de dados. Assim, uma aplicação em tempo real pode usar o RSVP para reservar os recursos necessários ao longo de todo o encaminhamento dos pacotes, a banda requisitada através desse protocolo. Dentro da abordagem de sistemas multimídia distribuídos, temos a utilização de um sistema com múltiplos discos para armazenagem de objetos de som e vídeo. De fato, a tendência é utilizar múltiplos discos na maioria das aplicações, seja para prover redundância, seja para obter uma maior capacidade de armazenagem. A segunda opção seria a mais aplicável aos sistemas multimídia distribuídos que requerem um espaço em disco considerável, especialmente quando estamos tratando de Vídeo on Demand (VoD). Podemos ter múltiplos discos num único computador, num dispositivo dedicado a armazenagem (storage) ou discos espalhados numa rede computadores utilizando, por exemplo, PVFS (Parallel Virtual File System). Assumindo servidores de sistemas multimídia com múltiplos discos, os blocos de dados são alocados nos discos de maneira a distribuir a carga de uma execução de um vídeo, por exemplo, igualmente entre os mesmos. Assim a forma de distribuir dos dados em conjunção com as técnicas de escalonamento podem afetar a apresentação contínua e o desempenho dos servidores multimídias. A duas abordagens amplamente conhecidas de alocar blocos de objetos multimídia entre controladores de múltiplos discos são: restrita e irrestrita. Um exemplo típico de alocação restrita de dados é o acesso aos discos utilizando a técnica round robin. 126

127 Um exemplo de alocação irrestrita de dados seria o acesso randômico aos discos. Baseados nas técnicas de alocação e escalonamento de dados, nós podemos classificá-las em quatro abordagens: Baseada em ciclos e alocação round robin; Controlada por deadline e alocação randômica; Baseada em ciclos e alocação randômica; Controlada por deadline e alocação round robin; Abordagem baseada em ciclos e alocação round robin: Muitos estudos investigaram a combinação escalonamento baseado em ciclos e alocação de dados em round robin. Com essa abordagem, um bloco é recuperado de cada controladora de disco para exibição num certo período de tempo. A carga do sistema deve ser distribuída entre as controladoras dos discos de modo a prevenir gargalos. Essa carga pode intencionalmente atrasar a recuperação de um primeiro bloco de um objeto requisitado sempre que um gargalo surge num disco. Devido a harmonia da alocação de dados em round robin e a recuperação periódica de dados baseada em ciclos, essa abordagem provê a garantia de um serviço determinístico livre de congelamento de imagem ou som num objeto multimídia, uma vez que sua recuperação é iniciada. Essa abordagem maximiza a utilização da largura de banda dos controladores de disco por distribuir a carga da exibição entre os discos igualmente. Assim, a vazão do sistema escala linearmente em função do número de controladores de discos no sistema. A desvantagem dessa abordagem seria a latência no início de recuperação dos dados. Assim esse sistema seria mais adequado para aplicação que requer uma vazão alta e poderia tolerar uma latência de início longo, como por exemplo, os sistemas de filmes sob demanda. Abordagem controlada por deadline e alocação randômica: Não muitos estudos têm investigado a abordagem com o escalonamento utilizando o conceito de deadline e a alocação randômica de dados. Através do controle dos deadlines para recuperação de blocos, essa abordagem pode prover uma latência mais curta para o início da recuperação dos dados do que a abordagem baseada em ciclos e round robin. 127

128 Dessa forma, essa abordagem é mais apropriada para aplicações que requerem uma latência de início curta tal como um sistema de editoração digital. Entretanto, essa abordagem pode permitir uma variação estatística no número de recuperações de blocos num disco. Devido à natureza da alocação dinâmica, um disco poderia receber mais requisições do que os outros. A formação de gargalo numa controladora de disco pode resultar na violação de deadlines estabelecidos nos blocos requisitados, causando congelamento na execução. Essa probabilidade pode ser significativa, dependendo da carga do sistema. Abordagem baseada em ciclos e alocação randômica: A abordagem de escalonamento cíclico e a alocação de dados randômica pode ser desconsiderada para uma análise mais aprofundada, devido suas desvantagens. Primeira, essa abordagem não pode prover a garantia de um serviço determinístico como com a baseada em ciclos e round robin, devido a alocação randômica dos dados. Segunda, essa abordagem não pode prover uma latência de início curta como a controlada por deadlines e randômica devido à alocação cíclica. Terceira essa abordagem resulta na baixa utilização da velocidade do disco porque as requisições podem ser distribuídas desigualmente entre os discos que finalizarem um ciclo mais cedo e assim ficarem inativos até que os outros discos terminem seus respectivos ciclos. Abordagem controlada por deadline e alocação round robin: De maneira similar, a abordagem de escalonamento controlado por deadline e alocação por round robin devido as suas desvantagens não convém ser considerada como uma alternativa viável. Com ela, uma vez que um gargalo ocorre num controlador de disco, ele ocorrerá repetidamente devido a alocação round robin e recuperação de dados sequencial na execução de objetos multimídia. O gargalo só acabaria quando um ou mais participantes do mesmo finalizassem a execução. Assumindo uma situação de filmes sob demanda, um gargalo poderia durar por o tempo de exibição do filme, no pior dos casos. Com a alocação dinâmica, o gargalo é resolvido mais rapidamente devido a carga ser distribuída baseada num padrão aleatório. 128

129 Video on Demand Um sistema de VoD (Video on Demand) pode ser usualmente considerado como um repositório variado de objetos multimídia com um grande de número de usuários dispersos. Esses objetos devem ser servidos aos clientes sob sua demanda. Geralmente um Servidor de Fluxo de Mídia Distribuído que atua como um VoD é posicionado numa rede com topologia hierárquica, com os Servidores Centralizados de Multimídia individuais como nós e os enlaces de rede como ligações na hierarquia. Os nós são capazes de armazenar um número limitado de objetos multimídia e podem afluir um número finito desses objetos. Das aplicações de multimídia distribuídas, como VoD, é esperado prover um serviço para um número significativo de clientes, algumas vezes dispersos geograficamente. Utilizar um único grande Servidor Centralizado de Sistemas Multimídia para suportar clientes distribuídos resultaria numa alocação ineficiente de recursos e num projeto virtualmente impraticável. A largura de banda necessária para implementar um VoD interativo com tal abordagem seria imensa. Por outro lado, utilizar um grupo distribuído mas independente de Servidores Centralizados de Sistemas Multimídia locais, isto é, num desenho distribuído sem compartilhamento de recursos, também se tem mostrado ineficiente. De fato, a ideia de conectar recursos em redes, seja em redes privadas seja na Internet, foi originalmente motivada por esse problema. O real potencial econômico de aplicações de multimídia distribuídas não será alcançado a menos que a efetividade dos custos da solução seja alcançada para servir os usuários dos sistemas multimídia. O foco dessa análise será aplicação VoD porém os princípios aqui discutidos poderão ser aplicados para outras aplicações de multimídia. Para suportar aplicação de fluxos distribuídos, existem pesquisas focadas em várias técnicas para, ou reduzir os requerimentos de banda de fluxos individuais de mídia, com métodos tais como smoothing (utilização de buferização para reduzir as rajadas na transmissão de conteúdos de multimídia), staging (utilização de servidores proxy colocados entre os clientes e os servidores de fluxos de multimídia) e negociação de banda, para reduzir o requerimento de banda como um todo via agregação ou a multiplexação estatística, utilizando, por exemplo, batching (técnica relacionada aos modelos hierárquicos de topologia de sistemas distribuídos de multimídia) e multicasting. 129

130 Com uma solução ortogonal, algumas pesquisas têm proposto uma distribuição de serviços para gerenciar a dispersão de clientes, por exemplo, empregando um número de Servidores Centralizados de Multimídia para atender clientes localizados em certos pontos e os conectando através de uma infraestrutura de rede de alta velocidade, para serem capazes de compartilhar ou intercambiar objetos de sistemas multimídia. É importante notar que embora atender os clientes localmente resulte numa redução dramática de consumo de banda, a menos que os servidores sejam capazes de compartilhar objetos na rede, o enorme requerimento de capacidade de armazenamento agregado dos servidores faz a abordagem de não compartilhamento impraticável. Sistemas projetados com base na abordagem de compartilhamento dos objetos têm-se mostrado uma solução eficiente, com um custo mínimo de transferência de objetos armazenados para aplicações de multimídia distribuída. Esses sistemas têm como uma das principais premissas a topologia hierárquica contemplando servidores e clientes. Além da topologia hierárquica, é esperado que os links das redes garantam os requerimentos de QoS (Quality of Service) da comunicação de sistemas multimídia. Temos algumas alternativas de infraestrutura de telecomunicações que podem prover esse tipo de serviço, como redes de circuitos comutados como o SONET (Synchronous Digital NETwork) que provê conexões físicas e/ou lógicas dedicadas, redes de comutação de pacotes que suportam serviços específicos como por exemplo o DiffServ do TCP-IP, emulando as características de circuitos dedicados através de garantia da qualidade do serviço por meio de mecanismos estatísticos ou determinísticos. Temos atualmente as redes MPLS (Multi-protocol Label Switching) que também já possuem suporte para sistemas multimídias. Os nós nas folhas no sistema hierárquico em árvore, chamados head-ends são pontos de acesso para o sistema. Na prática, os clientes são conectados aos headends através de redes de banda larga como xdsl e rede a cabo. Quando uma requisição de qualquer objeto chega ao head-end, se o objeto está disponível na armazenagem local o head-end atende o cliente, senão a requisição será enviada para os níveis mais altos da hierarquia e eventualmente algum outro nó que tenha armazenado localmente o objeto, atendendo ao cliente, transmitindo o fluxo multimídia através da topologia hierárquica, chegando ao head-end e finalmente no próprio cliente. 130

131 Como apresentado até o momento, um Servidor de Fluxo de Mídia Distribuído deve também consistir-se de um componente de middleware para gerenciamento de recursos. Supõe-se que esse midleware deva endereçar dois diferentes problemas ortogonais: Alocação de objeto. Mapeamento estático ou dinâmico de objetos em nós de rede de Servidores de Fluxo de Mídia Distribuído (espaço de armazenamento) para o custo total da comunicação de itens armazenados seja otimizado. Entrega de objetos. Sobre a demanda dos clientes em tempo real, posicionando réplicas de objetos dentro de uma rede de Servidores de Fluxo de Mídia Distribuído, selecionando uma réplica apropriada e os recursos do sistema de fluxos de mídia adequadamente (por exemplo, nó e largura de banda de um link) para a entrega de objetos, provendo uma eficiente utilização de recursos. Podemos perceber que os provedores de VoD precisam buscar o equilíbrio entre o posicionamento e capacidade dos Servidores de Fluxo de Mídia Distribuído e a velocidade dos links que conectam esses servidores entre si e entre os usuários finais. Provedores de VoD têm trabalhado em técnicas de codificação, decodificação e compressão de vídeos mantendo ainda assim uma boa definição. Além disso, eles possuem técnicas de levantamento do perfil dos usuários, recomendando conteúdos que serão migrados para Servidores de Fluxo de Mídia Distribuído mais próximos de cada usuário, minimizando assim custos. Conclusão do Capítulo Encerramos com esse capítulo a apresentação de elementos conceituais nos ajudarão a avaliar e compreender os modelos e tipos de clusters que iremos apresentar nos próximos capítulos desse trabalho. 131

132 Capítulo 2 Apresentação de Cluster em Linux na Modalidade HPC com ênfase em Kerrighed Considerações iniciais do capítulo Apresentaremos nesse capítulo os principais sistemas de cluster de alto desempenho em Linux na nossa visão, entrando num maior detalhamento quando abordarmos o sistema de cluster Kerrighed que será foco do nosso laboratório. Usaremos como comparação e contraponto ao cluster Kerrighed, o projeto OpenMosix que infelizmente foi encerrado por seu idealizador. Segue o motivo oficial do encerramento do projeto: O crescimento do poder e disponibilidade de processadores de multinúcleo de baixo custo está fazendo que rapidamente a clusterização com SSI (Single System Image) diminua sua importância na computação. A direção da computação é clara e as desenvolvedoras chaves estão migrando para novas abordagens de virtualização e outros projetos. Apesar de respeitarmos a opinião do criador do projeto, ainda achamos que plataformas como o OpenMosix ainda são viáveis técnica e economicamente, desde que implementadas de modo adequado, identificando, corrigindo e melhorando os sistemas como todo, sobretudo identificando os gargalos, verificando o comportamento e medindo o desempenho ao executar os diversos tipos de aplicações nesses ambientes. O projeto do OpenMosix, pelo menos, no que tange ao conceito de migração de processos tem sido continuado através do projeto LinuxPMI, porém sem ter um envolvimento efetivo da comunidade acadêmica e tecnológica. Classificação de Michael J. Flynn 15 (FLYNN, 1972) das arquiteturas de Computadores Michael Flynn concebeu uma classificação de arquiteturas de computadores através de modelos, baseada no número de fluxos de dados e de instruções existentes em cada instante que em sua concepção são quatro: 15 Michael J. Flynn é um cientista da computação dos Estados Unidos, professor emérito da Universidade de Stanford. Graduou-se em engenharia em 1955 pela Manhattan College e concluiu o mestrado cinco anos mais tarde, pela Universidade de Syracuse. Em 1961, concluiu o doutorado pela Universidade de Purdue. Propôs a taxonomia de Flynn em 1966, uma forma de classificação de arquiteturas de computador de acordo com instrução e fluxo de dado. 132

133 Arquitetura SISD (Single Instruction, Single Data): é o modelo mais simples, onde o computador processa sequencialmente, executando uma instrução por vez para cada dado enviado. É a arquitetura tradicional de Von Neuman. Arquitetura MISD (Multiple Instruction Single Data): é o modelo em que os computadores executam várias instruções ao mesmo tempo sobre um único dado. Não existe um computador real nesse modelo, pelo menos, atualmente. O próprio Michael Flynn duvidou pudesse existir algum modelo como esse no mundo real. Arquitetura SIMD (Single Instruction Multiple Data): é o modelo que usa o paralelismo de dados, onde uma simples instrução é executada paralelamente utilizando vários dados. Essa tecnologia é utilizada em alguns processadores, conhecida como MMX (MultiMedia extension) e também nos computadores vetoriais, computadores usados para efetuar operações aritméticas sobre vetores e matrizes de ponto flutuante. Arquitetura MIMD (Multiple Instruction, Multiple Data): é o modelo de execução paralela onde cada processador trabalha de maneira independente, ocorrendo múltiplos fluxos de instruções e múltiplos dados. Esse é o modelo utilizado nos clusters de computadores, utilizando a variação arquitetura MIMD com memória distribuída, que nesse caso seria vários computadores com seu próprio processador e memória executando múltiplas instruções com múltiplos dados conectados através de uma rede local. Tipos de clusters Podemos dividi-los em dois grupos, cluster de Alta Disponibilidade e cluster de Alta Performance de computação. Cluster de Alta Disponibilidade: Como o próprio nome já indica, o objetivo é manter o sistema o maior tempo possível na operação sem paradas não programadas, replicando os serviços e servidores. Quando algum serviço ou equipamento paralisar, os outros passam a responder automaticamente. Enquanto um servidor de boa qualidade, inclusive com redundância de discos rígidos, apresenta uma disponibilidade de 99,5%, um sistema de cluster de Alta disponibilidade apresenta 99,9%. 133

134 Esses quatro décimos podem parecer não muito significativos à primeira vista, mas para sistemas críticos são inestimáveis. Alguns sistemas de alta disponibilidade em Linux com o código fonte aberto são: LVS (Linux Virtual Server), Eddiware e o TurboLinux Cluster. Cluster de Alta Performance de Computação Esse modelo tem como foco desenvolver um sistema que tenha a mesmo poder de computação de um supercomputador, através do agrupamento de computadores numa rede de alta velocidade e softwares que agregam capacidade de memória e processamento desses computadores como se fosse apenas uma máquina, podendo assim executar aplicações que só seriam suportadas por supercomputadores ou computadores de grande porte. Nosso trabalho trata de Clusters de Alta Performance de Computação, sendo assim apresentaremos com mais detalhes alguns modelos que se enquadra nessa classe de agrupamento de computadores. Cluster Beowulf: O nome desse sistema vem de um dos mais antigos épicos da língua Inglesa, onde o protagonista é um cavaleiro inglês, de grande força e coragem, em sua luta contra o monstro de Grendel. Esse modelo de cluster foi concebido pela NASA com intuito de alcançar e avançar na capacidade de processamento massivamente paralelo (Massively Parallel Processing) MPP e aplicá-los para resolução de problemas computacionais, especialmente na aerociência e no projeto ESS (Earth and Space Sciences) a um baixo custo. Em 1994 o primeiro Cluster Beowulf foi finalizado com uma capacidade de processamento de 70 megaflops, que são setenta milhões de operações em ponto flutuantes por segundo. Ponto flutuante é uma forma de representação mais apropriada para computadores de números com muitas casas decimais. 134

135 Segundo Marcos Pitanga 16 (PITANGA, 2002), para um cluster de PC's ser considerado um Beowulf, precisa atender às seguintes características: Nenhum componente feito por encomenda; Independência de fornecedores de hardware e software; Periféricos escaláveis; Software livre de código aberto; Uso de ferramentas de computação distribuída disponíveis livremente com alterações mínimas; Retorno à comunidade do projeto e melhorias; O Beowulf tem como vantagem ser escalável, transparente ao hardware e sem nenhum custo em termos de software. Os elementos essenciais de um cluster Beowulf são: Os nós; O sistema operacional; A rede local; Os protocolos de rede local, no caso o TCP-IP; Os Clusters Middleware, que é a entidade que permite que os nós trabalhem como um recurso integrado, fornecendo ao usuário uma interface como se estivesse trabalhando num computador individual. As ferramentas de comunicação que usam como recurso o PVM (Parallel Virtual Machine), que permite a execução de programas paralelos em ambientes heterogêneos assim como o MPI (Message Passing Interface) que permitem a programação, através de troca de mensagens. Essas ferramentas também incluem API s (Application Programing Interface). 16 Marcos Pitanga possui mais de 23 anos de experiência em TI no Brasil e no exterior, com formação em Sistemas de Informações, com pós-graduação em Redes de Computadores e Segurança de Redes. Docente em algumas universidades nas cadeiras de Redes de Computadores, Sistemas Operacionais e Sistemas Distribuídos e Segurança de Redes. 135

136 Sistema de arquivos paralelo que são bibliotecas de interfaces que permitem visualizar os discos rígidos dos nós como se fosse um único disco virtual. Segue um esquema lógico simplificado de um cluster Beowulf: Figura 16 O nó controlador do cluster funciona como uma interface de saída para o acesso externo à outra rede, seja ela uma rede local ou a própria Internet. Os usuários se conectam nessa máquina para acessar os recursos do cluster. Os nós escravos são os computadores onde as aplicações serão executadas de modo paralelo, compartilhando assim os recursos de memória, processador e disco rígido. Um problema no modelo Beowulf é que se o nó controlador se danificar, perde-se toda a base de usuários, assim como o acesso aos nós escravos. Nesse caso recomendase uma redundância de disco nesse computador assim como uma política consistente de backup. 136

137 Cluster OSCAR (Open Source Cluster Application Resources): O OSCAR foi criado e é mantido pelo Open Cluster Group ( um grupo informal dedicado a simplificar a instalação e o uso de clusters, ampliando o seu uso. Ao longo dos anos muitas empresas têm suportado o Open Cluster Group, incluindo Dell, IBM, Intel, NCSA and ORNL, dentre outras. Como o OSCAR é desenvolvido como uma solução completa de clusterização há muitas áreas funcionais que precisam ser cobertas pelos componentes do mesmo. Essas áreas incluem instalação, ambiente de processamento paralelo, gerenciamento de carga de trabalho, segurança e administração e manutenção em geral. Para satisfazer o requerimento de cada área, os componentes do software incluídos no OSCAR foram selecionados através da investigação das práticas de muitas implementações independentes de computação em cluster. O resultado foi uma coleção de softwares que representam, segundo a proposta dos desenvolvedores do OSCAR, as melhores práticas para criar-se um exitoso ambiente de cluster. O OSCAR trabalha com o conceito de um servidor ou head e nós como indicado na figura abaixo. O servidor é dual homed, isto é, ele tem duas interfaces de rede. A interface conectada a rede externa é chamada public. A interface private conecta-se a rede do cluster. O OSCAR em sua instalação ativa um servidor DHCP (Dynamic Host Configuration Protocol) na interface private para fornecer endereçamento IP automático para os nós. Figura

138 O pacote de instalação do OSCAR é dividido em três partes principais: o core cuja instalação é mandatória, pacotes que são distribuídos como parte do OSCAR, mas a instalação é facultativa e os pacotes de desenvolvedores terceiros. Existem seis pacotes principais no OSCAR que precisam ser instalados: Core: o pacote principal do OSCAR. C3: o grupo de ferramentas para administração em linha de comando do cluster, para comandos e controle. Environmental Switcher: baseado em módulo, sendo um script em linguagem Perl que permite o usuário fazer mudanças para futuros ambientes shells. Oda: uma aplicação de base de dados central para o OSCAR. Perl-qt: a interface Perl orientada a objeto para o kit de ferramenta Qt GUI. SIS (System Installation Suite): utilizado para instalar o sistema operacional em clientes. Provavelmente a parte mais difícil na criação com sucesso de um ambiente em cluster seria a instalação inicial do software responsável por fazer máquinas independentes trabalharem juntas com um único recurso computacional. Incluso no pacote do OSCAR temos o LUI (Linux Utility for cluster Install), que é um projeto de software livre desenvolvido pelo Centro de Tecnologia de Linux da IBM. A principal razão de o LUI ter sido escolhido como mecanismo de instalação do OSCAR foi que ele não requer que os nós clientes já tenham o Linux instalado, nem requer uma imagem em disco para o nó cliente como outras técnicas de instalação requerem. O LUI apresenta uma série de qualidades, como um banco de dados que contém todas as informações para um nó instalar-se e configurar-se no cluster, a utilização de RPM (Red Hat Package Manager) e sua característica heterogênea, podendo ser instalado em hardwares e softwares diferentes. Tratando do processamento paralelo, o OSCAR suporta o conceito de passagem de mensagem e provê as implementações mais comuns a MPI (Message Passing Interface) e a PVM (Parallel Virtual Machine). Em meio às várias versões de MPI disponíveis, os desenvolvedores do OSCAR optaram pela MPICH (MPICHamaleon). 138

139 Projeto Rocks O projeto Rocks teve início em novembro de 2000, pelo SDSC (San Diego Supercomputer Center) que disponibilizou uma primeira versão conhecida como NPACI Rocks Cluster, que era um conjunto de ferramentas baseadas em Red Hat visando à construção e administração de maneira rápida e prática de clusters para a comunidade científica. Apesar de havermos apresentado brevemente o conceito de grid na introdução desse trabalho, como o Rocks tem uma aplicação também em sistemas em grid, vale elucidar um pouco mais o tema, apesar de o mesmo não ser o foco desse trabalho. A computação em grid é uma combinação de recursos computacionais de domínios administrativos múltiplos aplicados para uma tarefa comum, usualmente para solução de problemas de natureza científica, técnica ou corporativa que requer um grande número ciclos de processamento de computador ou necessite processar uma grande quantidade de dados. Uma das principais estratégias da computação em grid é utilizar softwares para dividir e aportar partes de programas em muitos computadores e formar uma rede de processamento paralelo e distribuído. O tamanho de um grid pode variar de muito pequeno, confinado a uma rede de computadores dentro de uma corporação, por exemplo, ou muito grande, através de uma colaboração pública entre muitas companhias e redes, usualmente utilizando a Internet como meio de comunicação. Dizemos que os sistemas em grid seria um cluster com computadores fracamente acoplados em termos de conexão de rede, pois não são recursos dedicados completamente à formação desse computador virtual como no caso dos clusters convencionais em que os componentes são considerados fortemente acoplados. O que também distingue a computação em grid dos clusters convencionais seria a heterogeneidade de seus componentes assim como a dispersão geográfica dos mesmos. Retornando aos conceitos do Rocks, um cluster com essa tecnologia tem a mesma arquitetura básica do OSCAR. O nó head também conhecido como front end é um servidor com duas interfaces de rede como ilustrado na Figura

140 O cluster Rocks tem os seguintes elementos principais: Controlador de dispositivos HPC (High Performance Computing); Monitoramento e Gerenciamento do estado do cluster; Gerenciamento do software do cluster; Camada de comunicação e passagem de mensagem; Aplicações para ambiente em cluster (Códigos Paralelos, Grid, etc); O Rocks é cluster completamente baseado em distribuição Linux Red Hat com pacotes adicionais e configuração programada para automatizar a implementação de um cluster Linux de alto desempenho. Escolha da distribuição Linux Red Hat, segundo os desenvolvedores, teve como motivo principal a existência de dois mecanismos chaves, a saber: o software de manipulação de pacotes RPM e sua ferramenta baseada em script para instalação, especialmente dos nós da solução (kickstart). Segundo os desenvolvedores, apesar do Rocks ter um foco num sistema rápido e flexível de configuração e reconfiguração, o comportamento estável do Rocks faz dele uma solução de cluster de mercado como Beowulf e o próprio OSCAR. Uma das premissas do desenvolvimento do Rocks foi criar um software de instalação, gerenciamento e monitoramento facilitado mesmo para clusters de grande porte, tornando acessíveis essas atividades mesmo para não especialistas. O mesmo possui um kit de ferramentas baseado na distribuição Red Hat, utilizando recursos de muitos projetos populares de grids e clusters. Adicionalmente, o Rocks permite que usuários finais adicionem seus próprios softwares através de um mecanismo chamado Rolls. Rolls que é uma coleção de pacotes e detalhes de configuração que podem ser modularmente acrescidos na base de distribuição do Rocks. 140

141 Cluster OpenMosix O projeto Mosix (Multicomputer Operating System UnIX), é um sistema operacional distribuído desenvolvido na Universidade Hebrew em Jerusalém, Israel. Sendo utilizado nos anos 80 pela Força Aérea Americana, chegando numa versão final desse projeto em 1997 utilizando plataforma Intel e sistema operacional GNU/Linux. O código do mesmo está disponível em gratuitamente apenas para instituições acadêmicas. O OpenMosix é um extensão do projeto Mosix, baseado em licença de software livre GPLv2 (hoje já temos a GPLv3), iniciando em 10 de fevereiro de 2002, sob coordenação do Ph.D Moshe Bar, visando manter essa solução de cluster como código aberto, devido divergências com a Universidade de Hebrew quanto a questão de direitos autorais. Durante a sua vigência o OpenMosix teve o apoio técnico e financeiro de muitas instituições privadas e públicas. Tendo como principal desenvolvedor o Dr. Moshe Bar, teve também ampla colaboração da comunidade acadêmica, destacando como membros do projeto, Dr. Maurizio Davini 17, Dr. David Santo Orcero 18, dentre outros. O OpenMosix é uma extensão de kernel criando um sistema de cluster de imagem única, sendo uma ferramenta para sistemas com kernel baseado em plataforma Unix, como o Linux, constituindo um algoritmo adaptativo de compartilhamento de recursos. Ele permite que múltiplas estações monoprocessadas e mesmo multiprocessadas simetricamente executem o mesmo kernel, podendo trabalhar numa significativa cooperação. Isso é alcançado através da migração de processos de um nó para outro de modo preemptivo e transparente, para balanceamento de carga e prevenção de trashing em processos de paginação de memória. O objetivo seria o melhor desempenho de modo geral num sistema de cluster e a criação de um ambiente multiusuário e time-sharing para a execução de aplicações sequenciais e paralelas. 17 Consultor da equipe Ferrari de corridas e chefe do Departamento de Física da Universidade de Pisa. 18 Consultor e professor da Universidade de Málaga. 141

142 Assim o OpenMosix é um sistema de cluster onde todos os recursos estão disponíveis em todos os nós que o compõe, podendo ser constituído de computadores de baixa capacidade de processamento e em redes convencionais, mas também podendo ser utilizado em ambientes com servidores de alta performance e em redes de alta velocidade e baixa latência. A granularidade no OpenMosix é determinada pela migração dos processos. Programas individuais podem criar processo ou processos que podem ser gerados através de múltiplos forks de um único programa. Entretanto, se temos uma tarefa intensiva em termos computacionais que é executada num simples processo, utilizando-se múltiplas threads, desde que não exista no próprio computador outro processador para compartilhar essa carga, esse processo seria elegível para ser migrado para outro nó do cluster. Naturalmente nem todos os processos são migrados num cluster OpenMosix. Por exemplo, se um processo dura poucos segundos, ele não terá tempo nem necessidade de ser migrado. Da mesma forma, múltiplos processos utilizando memória compartilhada, tais como servidores WEB, não são adequados para serem migrados, pois o OpenMosix não tem um sistema memória distribuída eficiente. Processos que atuam na manipulação direta de dispositivos de E/S também não migrados, porque o OpenMosix não possui um mecanismo de migração baseado em sockets. Similarmente os processos que utilizam escalonamento em tempo real também não seriam a princípio migrados. Existe uma proposta de pesquisadores da Syracuse University (OH, 2005), que utiliza uma combinação do Resource Kernel do Linux e do Mosix para executar tarefas em tempo real, podendo assim ser entendida para o OpenMosix. Podemos ver que apesar de ser uma solução elegante, especialmente no que diz respeito a não necessitar de um nó controlador, como no cluster Beowulf, que sempre será um ponto único de falha e de gargalo, o OpenMosix tem suas limitações e desvantagens. Assim ao utilizar essa plataforma há necessidade de escolher as aplicações compatíveis com a mesma. Seguem algumas diretrizes para um uso eficiente do OpenMosix. 142

143 Aplicações que têm um bom desempenho com o OpenMosix: Processos CPU-bound. Processos com longo tempo de execução e baixa utilização dos recursos de rede, por exemplo, aplicações científicas, matemáticas, de engenharia, etc. Compilações extensas. Processos com moderada comunicação interprocessos. Processos de uso intenso de E/S em disco, utilizando o sistema de arquivos distribuídos do OpenMosix. Bancos de dados que não utilizam memória compartilhada. Processos que podem ser migrados manualmente. Tecnologia do OpenMosix O OpenMosix é constituído de duas partes: o mecanismo PPM (Preempetive Process Migration) e um grupo de algoritmos para compartilhamento adaptativo de recursos. Ambas as partes são implementadas em nível de kernel, utilizando módulos carregáveis (via RPM ou compilação direta do kernel), de tal forma que a interface do Sistema Operacional permanece inalterada, sendo completamente transparente em nível de aplicação. O PPM pode migrar qualquer processo, a qualquer momento, para qualquer nó disponível. Usualmente as migrações são baseadas em informações providas por algum dos algoritmos de compartilhamento de recursos, mas os usuários podem sobrepor qualquer sistema automático de decisão e migrar seus processos manualmente. Cada processo tem um UHN (Unique Home-Node) gerado onde ele foi criado. Normalmente esse é o nó no qual o usuário executou o login. O modelo de imagem de sistema único do OpenMosix é coerente quanto ao cache, no qual cada processo aparenta estar sendo executado no seu próprio UHN e todos os processos de uma sessão de usuário compartilham o ambiente de execução do UHN. Processos que migram para outro nó usam os recursos locais (do nó remoto) sempre que possível, mas interagem com o ambiente do usuário através do UHN. 143

144 O PPM é a principal ferramenta para os algoritmos de gerenciamento de recursos. Enquanto o requerimento de recursos, tais como utilização de CPU e memória principal estiver abaixo de certos limites, os processos do usuário estarão confinados ao UHN. Quando os requerimentos de recursos excederem os níveis estabelecidos, então algum processo pode ser migrado para algum outro nó. O principal objetivo é maximizar o desempenho através de uma utilização eficiente dos recursos disponíveis na rede. O OpenMosix não tem um controle central no modelo mestre/escravo. Cada nó opera como um sistema autônomo, tomando as decisões de controle baseado nos algoritmos de controle de recurso que são executados no mesmo. Esse cenário permite a entrada e saída de nós com o mínimo impacto para o funcionamento do cluster como um todo. Essas funcionalidades permitem o sistema ser flexível no que tange à escalabilidade, operando com eficiência em pequenas e grandes instalações. Essa escalabilidade é alcançada porque a decisão de um nó em migrar um dado processo baseia-se num conhecimento parcial sobre o estado dos outros nós, tendo assim uma natureza probabilística. Algoritmos de Compartilhamento de Recursos Os principais algoritmos de compartilhamento de recursos do OpenMosix seria o balanceamento de carga e o uso de memória. O algoritmo dinâmico de balanceamento procura continuamente reduzir a diferença de carga entre os nós. O número de processadores e sua velocidade é um importante fator nas decisões tomadas por esse algoritmo. Ele operará adequadamente até haver recursos disponíveis no cluster como um todo. O algoritmo de uso memória atua na prevenção do esgotamento na mesma, sendo projetado para alocar um número máximo de processos no agregado de memória RAM do sistema, evitando trashing e/ou excessivos swapping de processos. O algoritmo é ativado quando se percebe que um nó começa a ter excessivas paginações devido ao esgotamento da memória, nesse caso o algoritmo de controle de memória, sobrepõe-se ao algoritmo de balanceamento de carga e faz uma tentativa de migrar algum processo para um nó com memória RAM disponível. 144

145 Migração de Processos O OpenMosix possui um processo preemptivo e completamente transparente de migração de processos através do PPM. Depois da migração, o processo continua interagir com seu ambiente de origem independente de sua localização. Para a implementação do PPM, o processo de migração é dividido em dois contextos: contexto do usuário, que pode ser migrado e o contexto do sistema, que é dependente do UHN e não pode ser migrado. O contexto do usuário, conhecido como remote contém o código do programa, a pilha, os dados, o mapeamento de memória e o estado dos registradores do processo. O remote encapsula o processo quando o mesmo está sendo executado em nível de usuário. O contexto do sistema, conhecido como deputy encapsula o processo quando ele está sendo executado em modo kernel. O deputy contém a descrição dos recursos que estão associados ao processo e a pilha do kernel para a execução do código do sistema referente ao mesmo. Ele mantém parte local do processo no contexto do sistema, permanecendo no UHN. O deputy nunca é migrado. A interface entre o contexto do usuário e o contexto do sistema é muito bem definida. Portanto é possível interceptar toda a interação entre os contextos e encaminhar essa interação através da rede. Essa implementação é feita via camada de enlace sob o ponto de vista do modelo ISO/OSI. O tempo de migração tem um componente fixo para estabelecer uma instância do novo processo no nó remoto, sendo um componente linear, ele é proporcional ao número de página de memória a serem transferidas. Para minimizar o overhead da migração apenas as tabelas das páginas e as páginas sujas (páginas de retiradas da memória física, mas que foram modificadas e precisam ser armazenadas no arquivo swap) são transferidas. Na execução de um processo no OpenMosix, a transparência de localização é alcançada pelo encaminhamento das chamadas de sistemas dependentes do kernel para o deputy no UHN. As chamadas de sistema são interações síncronas entre dois contextos de processos. 145

146 Acesso a arquivos: O OpenMosix tem seu próprio sistema de arquivo para cluster em Linux que dá uma visão na perspectiva de cluster de todos os sistemas de arquivos que o compõe. O OpenMosix usa o DFSA (Direct File System Access). O DFSA foi projetado para reduzir o overhead para se executar chamadas de sistemas orientadas a E/S de processos migrados. Ele basicamente faz isso, migrando os processos para os computadores que tem uma maior demanda de E/S de disco, diferentemente de outros sistemas de arquivos distribuídos como, como por exemplo, o NFS. Sistemas de Arquivos Para suportar o DFSA foi desenvolvido o omfs (open Mosix File System) que provê uma sistema único de localização de arquivos, considerando o sistema de arquivos de cada nó do cluster. A consistência de cache é obtida através da manutenção de um único servidor de cache tendo os outros nós como clientes que apenas repassam as requisições de acesso ao cache desse servidor. A principal vantagem dessa abordagem seria a escalabilidade na consistência de cache mesmo para um número significativo de processos. Infelizmente o omfs foi retirado dos últimos pacotes liberados pelo OpenMosix, segundo os desenvolvedores por questões de segurança. Mecanismos do Deputy e do Remote O deputy é o representante do processo remote no UHN. Devido a todo espaço de memória de usuário residir no nó remoto, o deputy não possui nenhum mapeamento de memória próprio. Ao invés disso, ele compartilha o mapeamento principal do kernel de modo similar a uma thread. Em muitas atividades de kernel, tais como chamadas de sistema, é necessária a transferência de dados do espaço do usuário para o kernel. No OpenMosix, qualquer operação de memória do kernel que envolva o acesso ao espaço do usuário requer que o deputy se comunique com o remote para transferir-se os dados necessários. Para minimizar o overhead de cópias de dados na comunicação entre contextos, um cache especial é implementado visando a diminuição de cópias remotas, mantendo a quantidade de dados possível no deputy em buffer no início da chamada de sistema para serem enviados apenas no final da mesma. 146

147 Coleta de Informações Estatísticas sobre o comportamento dos processos são coletadas regularmente, tais como todas chamadas de sistemas e todo o tempo em que o processo acessa dados de usuário. Essa informação é utilizada para avaliar se o processo precisa ser migrado do UHN. Essa estatística é alterada no tempo, ajustando-se a processos que alteram seu perfil de execução. API do OpenMosix: A API do OpenMosix foi originalmente implementada através de um grupo reservado de chamadas de sistemas que eram usadas para configurar, pesquisar e operar o OpenMosix. Seguindo a convenção atual do Linux, a API foi modificada para fazer interface com sistema de arquivo /proc. Isso evita possíveis incompatibilidades de programas de usuários entre diferentes versões de Linux. A API foi implementada através da extensão da árvore do sistema de arquivo /proc com um novo diretório: /proc/openmosix. As chamadas para o OpenMosix via /proc incluem: requisições de migração síncronas e assíncronas, lock de um processo contra migrações automáticas; verificação de onde os processos estão correntemente sendo executados, identificação de restrições para migrações, administração do sistema, controle da coleta de estatísticas e informação sobre processos remotos. Segurança no OpenMosix: Devido a sua arquitetura e modus operandi, o OpenMosix possui algumas questões de segurança inerentes a plataforma, como por exemplo, a relação de confiança entre os nós do cluster, a necessidade de comunicação entre todos os nós de forma praticamente permanente, a facilidade de um invasor editar o mapeamento dos nós do cluster no arquivo openmosix.map e a própria aplicação de descoberta automática de nós omdiscd que trabalha com multicast, fazem o OpenMosix frágil nos limites que seus desenvolvedores chamam de parte interna (inside) do cluster. O próprio Dr. Moshe afirma que as políticas de segurança deveriam ser aplicadas no perímetro do cluster e não dentro no mesmo, ao responder um questionamento sobre a vulnerabilidade do sistema a ataques de DoS (Denial of Service). 147

148 Tratando de mitigações, existem algumas distribuições do OpenMosix como o CHAOS que substitui a aplicação em multicast do omdiscd pela aplicação tyd que trabalha com unicast como um gatekeeper num ambiente VoIP ou mesmo um servidor WINS da plataforma Microsoft. O tyd em si não implementa qualquer funcionalidade de segurança, mas como ele trabalha com pacotes unicast, o mesmo provê um ambiente mais acessível para aplicar tecnologia como IPSec possibilitando a criação de VPN s entre os nós. Tendo apresentado uma solução de contorno para prover certo nível de segurança entre os nós do cluster, mesmo que ainda não completo, pois o tyd não possui nenhum dispositivo de autenticação, precisamos também analisar a questão da rede inside e a rede outside. Como já visto a rede inside é a rede que provê a comunicação entre os nós que usualmente trabalha com as portas UDP e TCP 723 e A rede outside é a rede conectada ao mundo externo seja uma rede local onde o cluster estaria conectado, seja uma conexão direta com a Internet. Via de regra, o tráfico inside não deve ser acessado pela rede outside sem um mínimo nível de segurança. A solução para manter essa separação lógica, seria colocar uma segunda interface de rede num dos nós do cluster conectado na rede outside, ativando a funcionalidade de firewall (Netfilter) no mesmo, para que através de filtros, o tráfego interno não seja acessado externamente. Essa solução não seria a mais adequada pois traria para o OpenMosix a mesma inconveniência dos modelos de cluster com um nó controlador, ou seja um ponto único de falha e de gargalo. Soluções mais elaboradas podem ser utilizadas colocando um firewall entre as duas redes que seriam confinadas através de VLAN (Virtual Local Area Network). 148

149 Iniciativas de melhorias do OpenMosix Durante seu ciclo de vida, o OpenMosix teve algumas iniciativas isoladas de melhorias visando, seja aprimorar funcionalidades, seja prover soluções para deficiências intrínsecas do sistema. Podemos citar o grupo, na ocasião de estudantes da Universidade de Puna, Índia, Maya, Anu, Asmita, Snehal and Krushna (MAASK, 2003) que desenvolveram o MigShm um kernel patch ao OpenMosix visando otimizar a funcionalidades de memória compartilhada do mesmo. Uma das limitações do OpenMosix é executar aplicações que utilizam memória compartilhada e multi-threads, pois elas não conseguem ser migradas, não podendo assim ser beneficiadas pela principal característica do OpenMosix que é a migração de processos. O MigShm tem como pretensão realizar a migração de memória compartilhada. Ele não é exatamente um completo DSM (Distributed Shared Memory), mas é suficiente para endereçar algumas situações de memória compartilhada no OpenMosix. Para o desenvolvimento do Migshm foi necessário a criação de algumas chamadas de sistemas tais como shmget(), shmat(), shmdt() e shmctl(). Cada uma dessas funções é disponibilizada transparentemente no remote e quando da necessidade da migração de processos com memória compartilhada, essas chamadas acessam o mapeamento local de memória. Um módulo de comunicação é necessário para obter-se uma comunicação entre o deputy e o remote para as tratativas do Migshm. O MAASK utilizou o Commlink para esse propósito, entretanto para garantir a comunicação entre dois processos em nós diferentes, elas também implementaram um daemon em cada nó do OpenMosix chamado MigSharedMemD, que utiliza o port TCP

150 Diferentes processos utilizando mesma região compartilhada podem migrar para diferentes nós, onde eles trabalham com cópias locais dessa memória compartilhada. A consistência é mantida entre as diferentes instâncias cópias locais, através do modelo de consistência Eager Release, que implementa um mecanismo onde cópias locais de páginas modificadas serão apenas escritas no processo que as originou quando o lock desse segmento de memória for liberado e não para qualquer escrita. Isso garante que o nó originador da memória compartilhada sempre terá a cópia mais atual da mesma. Travis Frisinger do departamento de Ciência da Computação da Universidade de Wisconsin-Eau Claire que no seu artigo A Modification of OpenMosix s Process Migration propõe um controle maior no processo de migração OpenMosix, pois cada canal criado para esse fim consome uma quantidade significativa de recursos. Sua proposta seria reutilizar o canal para migrar mais de um processo por vez, economizando assim os recursos dos nós de um cluster OpenMosix. Apesar do ganho em desempenho, ser relativamente pequeno por nó, em torno de 2%, segundo o autor, o mesmo será mais significativo em clusters com uma quantidade significativa de computadores na ordem de centenas. 150

151 Cluster Kerrighed O cluster Kerrighed tem muitas similaridades com o OpenMosix, especialmente no que tange a ser um cluster de imagem única (SSI) e também por trabalhar com a migração de processos. Porém o cluster Kerrighed avançou em algumas funcionalidades as quais são ineficientes ou inexistentes no OpenMosix, como por exemplo, um compartilhamento de memória eficaz e a migração de threads. O principal objetivo Kerrighed é prover serviços de alto nível na execução de aplicações sequenciais e paralelas num sistema de cluster. No Kerrighed todos os recursos de cada nó que o compõe (processadores, memória, discos, etc) são globais e dinamicamente gerenciados. O gerenciamento global de recursos habilita uma distribuição transparente dos mesmos entre os nós e um uso adequado dos recursos do cluster como um todo, por aplicações que os demandem. O gerenciamento dinâmico dos recursos habilita uma reconfiguração transparente do cluster (adição e retirada de nós), causando nenhum impacto na execução das aplicações, mesmo em eventos de falha de algum nó do cluster (Alta Disponibilidade). Em adição, um mecanismo de checkpointing é provido para evitar a reinicializarão de aplicações (pelo menos desde seu início) quando uma falha de um nó ocorre. O Kerrighed é implementado como uma extensão de um sistema operacional padrão em cada nó, baseado em Linux kernel. No Kerrighed, processos e threads podem iniciar sua execução em qualquer nó, podendo ser migrados durante sua execução. Mecanismos eficientes de gerenciamento de processos são implementados no Kerrighed para prover um escalonamento global. O gerenciamento global de memória no Kerrighed baseia-se no conceito de container. Baseando-se em containers, os serviços de alto nível de um sistema operacional padrão podem ser executados elegantemente de modo a prover segmentos de memória virtual, arquivo de cache corporativo, paginação remota e uma forma eficiente de se transferir o espaço de memória de processos migrados. A camada de comunicação do Kerrighed é baseada no novo conceito de Fluxos Dinâmicos (Dynamic Streams), implementando o padrão de interface em camadas que é suportado pela maioria das aplicações, provendo uma comunicação eficiente na migração de processos. 151

152 Do ponto de vista dos desenvolvedores do Kerrighed, um SSI deve possuir quatro propriedades, a saber, distribuição transparente de recursos, oferecendo a ilusão que todo recurso é único e compartilhado, alta desempenho, alta disponibilidade e escalabilidade. Segundo seus desenvolvedores essas propriedades existem no Kerrighed por meio de um gerenciamento global e dinâmico de recursos. A principal vantagem da abordagem do Kerrighed é a interface padrão que cada nó que o compõe possui, interface essa familiar aos desenvolvedores de aplicações. Assim aplicações já existentes que são executadas em sistemas operacionais tradicionais, são migradas para o Kerrighed sem nenhuma modificação, podendo posteriormente ser otimizadas para usufruírem melhor das funcionalidades do cluster. O Kerrighed não é um sistema operacional desenvolvido totalmente do início, mas de fato, ele é implementado como uma extensão do sistema operacional tradicional existente. O Kerrighed apenas atua nas atividades de natureza distribuída próprias do sistema de cluster, deixando para cada nó a tarefa de gerenciar os recursos locais. Gerenciamento Global de Processos Características principais: Um processo que é manipulado pelo Kerrighed passa a chamar-se de K-process. Todo o espaço de memória utilizado por K-process está ligado aos containers. Esses K-process são migrados dentro do cluster para um melhor aproveitamento dos recursos e para igualizar a carga de trabalho entre os nós que compõe o mesmo. Essa igualdade da carga de trabalho é obtida através de uma escolha cuidadosa em qual nó cada processo deve ser executado. A política de escalonamento do Kerrighed define como os processos são mapeados entre os nós, baseando esse mapeamento em alguns objetivos a serem alcançados como, por exemplo, balanceamento entre as CPU s. Ele também utiliza como parâmetros a serem considerados nessa política, o uso de CPU por processo e o estado de cada nó como, por exemplo, o número de processos que estão sendo executados em cada um deles. Assim o papel da política global de escalonamento é manter o cluster num estado de equilíbrio no que tange ao uso dos recursos, criando processos de maneira criteriosa ou migrando-os quando ocorrer algum desvio. 152

153 Mas, além disso, um scheduler num cluster necessita ter a possibilidade de ser passível de configuração quando ocorrer algum cenário em termos de utilização processamento ou de recursos não contemplados pela política de escalonamento do cluster ou que para o qual os algoritmos de escalonamento não conseguem prover resultados adequados. A política de escalonamento do Kerrighed pode ser facilmente alterada pelo administrador do mesmo, se necessário. O scheduler do Kerrighed baseia-se num conjunto de mecanismos eficientes de gerenciamento de processos. Criação remota de processos e threads, migração de processos e threads são usadas para diminuir a contenção de recursos locais assim como evitar a execução de aplicações em nós que necessitam ser desativados (para manutenção, por exemplo). O processo de checkpointing ajuda a diminuir a contenção global nos recursos por colocar em suspensão algumas aplicações. Esses mecanismos são todos baseados nas funcionalidades e estados dos processos que são executados no sistema operacional local. Num sistema padrão Linux, processos e threads podem ser criados usando interfaces fork e execv. Na interface padrão de threads no Posix, é permitida a criação e o gerenciamento das mesmas em aplicações de memória compartilhada. No Kerrighed, esses mecanismos são ampliados através dos mecanismos de gerenciamento de processos para que aplicações legadas desenvolvidas para computadores SMP (Symmetric Multiprocessing) possam obter vantagens na utilização de clusters. Escalonamento Global alterável e modular: O Kerrighed propõe um escalonamento global modular, composto de três camadas: Probes do Sistema para coleta de informações do mesmo, provendo assim uma visão do estado do cluster; Analisadores locais para detectar todos os problemas locais de escalonamento tais como alta contenção de recursos e falhas em dispositivos; Gerenciador global de escalonamento para ativar novos processos e resolver problemas de escalonamento; Essa arquitetura modular permite interagir separadamente com diferentes aspectos do escalonamento global, e assim facilitar modificações na suas políticas. 153

154 Probes do Sistema, medindo, por exemplo, o uso de CPU ou memória constituem-se na primeira camada. Existem dois tipos de probes, passivas e ativas. Cada probe pode ser ligada a um grupo de analisadores locais, para os quais ela envia informação. Probes ativas são regularmente acionadas por um temporizador do sistema, enquanto probes passivas são acionadas por um evento do sistema. Existem dois diferentes eventos do sistema: eventos do kernel do Linux e eventos do scheduler global, esse último coleta informações locais. Quando uma probe passiva é acionada por um evento do sistema, a probe envia a informação coletada para o analisador local com o qual ela está ligada. Por exemplo, uma probe ativa pode ser usada para verificar a utilização de CPU (a CPU é periodicamente verificada), enquanto que se utiliza uma probe passiva para detectar um ping-pong de páginas de memória entre duas threads de uma aplicação de memória compartilhada (quando uma página chega ao nó, a probe é acionada). O Kerrighed provê um conjunto de probes na sua implementação, podendo novas probes ser desenvolvidas por programadores de sistemas operacionais. Analisadores locais recebem as informações das probes, as analisa e filtra, detectando algum estado anormal do sistema local. Essa camada também tem a função de enviar as informações das probes para gerenciador global de escalonamento. Um grupo de analisadores locais é executado em cada nó. Cada analisador local pode estar ligado a um conjunto de probes. Por exemplo, podemos ter uma probe para o consumo de CPU e outra para a temperatura da mesma. O analisador local ligado a essas duas probes pode detectar uma alta contenção local de CPU, assim como problemas locais de temperatura. Se um problema de CPU é detectado, o analisador local envia uma requisição para o gerenciador global de escalonamento (o analisador local não tem uma visão geral do estado do cluster e, portanto, não pode tomar uma decisão nesse nível). 154

155 Um gerenciador global de escalonamento é executado em cada nó, sendo ligado a um grupo de analisadores locais. Os gerenciadores globais de escalonamento executados em diferentes nós comunicam-se entre si para trocar informação do estado de cada nó que compõe o cluster. Essa camada é a única que tem uma visão global do mesmo. Essa visão global é construída com as informações das probes (por exemplo, probes de CPU), habilitando a detecção global de problemas de escalonamento. Para esse fim, cada gerenciador global de escalonamento implementa uma política global de escalonamento ( por exemplo, o balanceamento de CPU). Quando um problema de escalonamento é detectado (por exemplo, CPU s locais com mais carga do que a média do cluster), o gerenciador global de escalonamento pode decidir migrar alguns processos ou acionar um checkpointing para alguma aplicação, de acordo com a política de escalonamento, a fim de obter um uso eficiente dos recursos do cluster. Essas três camadas que compõe o escalonamento global modular do Kerrighed podem ser configuradas usando arquivos XML. Diferentes probes, analisadores locais e gerenciadores globais de escalonamento podem ser dinamicamente ativados e desativados sem a necessidade de se encerrar nem o sistema operacional nem as aplicações. Além disso, cada camada provê uma estrutura de desenvolvimento para facilitar a programação de novos componentes, permitindo, de maneira simples, a criação de novas políticas de escalonamento global. Finalmente, o scheduler do kernel do Linux não é modificado. O Kerrighed apenas adiciona ou remove processos no scheduler local. 155

156 Gerenciamento do estado dos processos Os schedulers do Kerrighed são baseados em três mecanismos: estabelecimento, migração e check-point/restart de processos. Para o estabelecimento, o Kerrighed provê dois mecanismos: criação remota de processos e duplicação remota de processos. A criação remota de processos utiliza uma interface dedicada semanticamente equivalente a um fork(), imediatamente seguido por um execv() no processo filho. A duplicação de processos é utilizada na execução de aplicações quando um novo processo (usando fork) ou threads (usando pthread create) são criados, necessitando herdar o contexto da aplicação. Para estabelecer um novo processo, o sistema necessita extrair uma imagem do processo criador e transferi-lo para um nó remoto, criando um clone que será executado no mesmo. Similarmente para uma migração remota de processo, essa migração precisa extrair uma imagem do processo e transferi-la para o nó remoto, criando um clone do mesmo, mas o processo original é finalizado. O checkpointing de processo também necessita extrair uma imagem do mesmo e armazená-la no disco ou numa memória remota. A criação, duplicação e checkpoint/restart de um processo Kerrighed utilizam o mesmo mecanismo fundamental de extração de processo. A extração de um processo consiste na criação de um processo ghost (virtualização de processo) composto dos seguintes componentes: espaço de endereçamento, arquivos abertos, Identificador de Processo (PID), registradores do processador e os próprios dados. Gerenciamento de espaço de endereçamento e arquivos abertos: De modo similar a um kernel padrão do Linux, que necessita extrair todas as informações de memória e arquivos abertos a fim de criar um processo ghost coerente, no Kerrighed o espaço de endereçamento e os arquivos abertos de um K- process são globalmente gerenciados. O espaço de memória e arquivos convencionais abertos são tratados pelos containers e os arquivos de stream por mecanismos de dynamic streams (fluxos dinâmicos). Através dos containers tanto arquivos abertos como páginas de memória podem ser acessados por qualquer nó do cluster, que viabiliza consideravelmente a migração de processos. 156

157 Gerenciamento do Identificador de Processo (PID): No Linux padrão as threads são implementadas por processos utilizando a biblioteca pthread. Então, os processos são identificados por um Process Identifier (PID). As threads são distinguidas por identificadores internos na biblioteca pthread. O Kerrighed adiciona uma camada ao sistema. Para cada processo é designado um Kerrighed Process Identifier (KPID), como o seu PID. Em nível de kernel, o PID é usado, enquanto que em nível de usuário, apenas o KPID é visualizado. Dessa forma um único KPID é designado para um processo em todo cluster. Para garantir a unicidade, um KPID é composto do PID original e o identificador do nó corrente. A biblioteca de thread do Kerrighed gerencia o identificador adicional de thread. Gerenciamento Global de Memória O gerenciamento global de memória num cluster abrange muitos serviços. Primeiro, a fim de suportar a execução de aplicações multi-thread e modelos usuais de programação em ambiente de memória compartilhada, um sistema de DSM (Distributed Shared Memory) é necessário, permitindo que processos e threads compartilhem segmentos de dados em qualquer nó do cluster. Segundo, é muito desejável num cluster explorar a memória que está distribuída entre os nós, para aumentar a eficiência dos serviços do sistema operacional. Existem duas áreas chaves no gerenciamento de memória num cluster, um mecanismo remoto de paginação e um mecanismo cooperativo de arquivos de cache. Num sistema de DSM, os sistemas de paginação de memória e de arquivos de cache cooperativos baseiam-se em mecanismos comuns: localizar a cópia de uma página de memória no cluster, transferir páginas entre nós e gerenciar a coerência de cópias de páginas replicadas. O Kerrighed implementa o conceito de container como um único mecanismo para gerenciar globalmente as memórias físicas do cluster. Todos os serviços do sistema operacional que utilizam páginas de memória acessam a memória física através de containers. 157

158 Containers Num cluster, cada nó executa o seu próprio kernel do sistema operacional, o qual pode ser dividido de modo grosseiro em duas partes: serviços de sistema e gerenciadores de dispositivos. O Kerrighed propõe um serviço genérico inserido entre os serviços de sistema e os gerenciadores de serviços chamados de containers. Os containers são integrados ao kernel graças aos linkers que são partes de software inseridas entre os gerenciadores de dispositivos existentes, os serviços de sistema e os containers. A ideia principal do container é que ele dá a ilusão aos serviços de sistemas que a memória física é compartilhada como um computador SMP (Symmetric Multiprocessing). Um container é um objeto que permite que o armazenamento e compartilhamento de dados em toda extensão do cluster. Ele atua em nível de kernel, sendo completamente transparente em nível de software de usuário. Os dados armazenados num container podem ser compartilhados e acessados pelo kernel de qualquer nó do cluster. As páginas de um container podem ser mapeadas num espaço de endereço de um processo, podendo assim ser utilizadas como entrada de arquivo de cache, dentre outras aplicações. Por integrar esse mecanismo genérico de compartilhamento dentro do sistema, é possível dar a ilusão para o kernel que ele está manipulando uma memória física. Sobre essa memória virtual compartilhada é possível estender ao cluster os serviços tradicionais oferecidos por um sistema operacional padrão. Isso permite manter a interface do sistema operacional já conhecida pelos usuários, tirando vantagem do gerenciamento de recursos locais de baixo nível. O modelo oferecido pelos containers é sequencialmente consistente, implementado com um protocolo write-invalidate. Linkers Muitos mecanismos num kernel apoiam-se no manuseio de páginas físicas. Os linkers desviam esses mecanismos para garantir o compartilhamento através dos containers. Para cada container são associados um ou mais linkers de alto nível chamados linkers de interface e linkers de baixo nível chamados linkers de input/output. A função do linker de interface é desviar o acesso aos dispositivos de serviços do sistema para os containers enquanto um linker de E/S permite o acesso a um gerenciador de dispositivo. 158

159 Os serviços de sistemas são conectados aos containers graças aos linkers de interface. Um linker de interface muda a interface do container para fazê-la compatível com a interface de serviços de sistema de alto nível. Essa interface precisa dar a ilusão para esses serviços que eles se comunicam com gerenciadores de dispositivos tradicionais. É possível conectar vários serviços de sistema a um mesmo container. Durante a criação de um novo container, um linker de E/S é associado ao mesmo. O container deixa de ser então um objeto genérico para tornar-se um objeto de compartilhamento de dados, vindos do dispositivo ao qual ele está ligado. Design dos Serviços de Sistema Distribuídos Os containers e linkers são utilizados para implementar vários serviços que compõe um cluster, dentre eles memória virtual compartilhada e serviços de mapeamento de arquivos. Memória Virtual Compartilhada A memória virtual compartilhada no Kerrighed estende esse serviço ao cluster por permitir que vários processos ou threads sejam executados em nós diferentes, compartilhando dados através do seu espaço de endereçamento. Para que esse serviço seja provido, são requeridas três propriedades: compartilhamento de dados entre os nós, coerência na replicação de dados e acesso simples a dados compartilhados. Os serviços do container garantem as duas primeiras propriedades, enquanto que a terceira é garantida pelo mapeamento do linker de interface. Assim, mapear um container de memória em espaços de memória virtual de vários processos via um mapeamento de linker, leva a uma memória virtual compartilhada. Mapeamento de Arquivos O serviço de mapeamento de arquivos de um sistema operacional convencional permite mapear um arquivo no espaço de endereço de um ou mais processo, ou no espaço de endereço compartilhado por um grupo de threads. Estendendo esse serviço a um cluster considera-se o mapeamento de um arquivo no espaço de endereço de um processo não importando onde será sua execução, seja em seu nó do cluster seja numa memória compartilhada de um grupo de threads. Isso é feito por mapear um arquivo de container num espaço de memória virtual de um processo graças a um mapeamento de um linker de interface. 159

160 Dynamic Streams (Fluxos dinâmicos) O Kerrighed implementa um balanceamento de cargas de trabalho compostas de aplicações paralelas, baseando-se em memória compartilhada ou em modelos de programação de message passing. Um desafio é migrar eficientemente processos utilizando message passing. Processos que se comunicam utilizando interfaces padrão tais como sockets ou pipes devem ser capazes de serem transparentemente migrados num cluster. Além disso, migrar processos não deveria alterar o desempenho de sua comunicação com outros processos. As interfaces padrão de comunicação tais como pipes e sockets, utilizam um fluxo binário para realizar a comunicação entre processos. O Kerrighed propõe um conceito de fluxo dinâmico, sobre o qual interfaces padrão de comunicação são desenvolvidas. As extremidades desses fluxos são chamadas KerNet sockets e os mesmos podem ser migrados dentro do cluster. Fluxos dinâmicos e KerNet sockets são implementados no topo de um sistema portável de comunicação de alta performance, provendo uma interface de envio/recepção para transferir dados entre diferentes nós num cluster. Os fluxos dinâmicos e o KerNet sockets são implementados na camada KerNet. Ela é um serviço distribuído que provê gerenciamento global de fluxos em todo cluster. Serviço de Fluxo Dinâmico Todos os clusters baseiam-se num sistema de comunicação ponto a ponto de baixo nível. Na maioria das vezes, tais sistemas proveem propriedades tais como confiabilidade, alta performance e ordenação de mensagens. Assim, quando a migração não ocorre, as aplicações devem ser capazes de tirar vantagem dessas propriedades. O Kerrighed possui um sistema de comunicação de baixo nível que é confiável e mantém a ordem das mensagens enviadas entre dois nós. O fluxo dinâmico KerNet é uma abstração de fluxo com dois ou mais KerNet sockets definidos e com nenhum nó especificado. Quando necessário, um KerNet socket é temporariamente associado a um nó. Por exemplo, quando dois KerNet sockets estão conectados, uma operação de envio/recepção pode ocorrer. 160

161 Seguem alguns dos principais parâmetros do fluxo dinâmico KerNet: Tipo de fluxo Número de sockets Número de sockets conectados Filtro de dados Fluxos são controlados por um grupo de gerenciadores, cada um deles localizado num nó do cluster. Estruturas de dados do kernel relacionadas com fluxos dinâmicos são mantidas num diretório global que é distribuído entre os nós cluster. Dados como a localização do nó de um KerNet socket, são atualizados em todos nós ativos no fluxo. O serviço de fluxos dinâmicos é responsável por alocar KerNet sockets quando necessário, assim como monitorar os mesmos. Quando um estado de um KerNet socket muda, o gerenciador de fluxo é acionado e atualiza os outros KerNet sockets relacionados a esse fluxo. Com esse mecanismo, cada KerNet socket tem o endereço do socket de cada nó correspondente num mapeamento. Quando conexão termina, o processo é desconectado do fluxo. Dependendo do tipo de fluxo, o mesmo pode ser fechado. Implementação de Interfaces de Comunicação Padrão usando Fluxos Dinâmicos Aplicações distribuídas padrão, obviamente não utilizam KerNet sockets. A fim de criar um ambiente padrão baseado em fluxos dinâmicos e KerNet sockets, uma camada de interface é implementada em nível de kernel. O principal objetivo desse módulo é gerenciar o protocolo de interface de comunicação padrão, se necessário. As interfaces KerNet são ligações entre o sistema operacional Linux padrão e o serviço dinâmico de comunicação do Kerrighed. 161

162 O sistema operacional do Kerrighed é desenvolvido sobre um kernel levemente modificado de Linux. Todos os diferentes serviços, incluindo a camada de comunicação, são implementados como módulos do Linux. A camada de comunicação é constituída de duas partes: um sistema de comunicação estático de alto desempenho que provê um serviço nó para nó e um serviço de interface que substitui as funções padrão para uma dada ferramenta de comunicação. Camada de comunicação de baixo nível A arquitetura do KerNet é projetada para sistemas operacionais distribuídos tais como o Kerrighed. Por essa razão, foi natural desenvolver o KerNet no topo da camada de comunicação de baixo nível provida pelo Kerrighed, chamada Gimli/Gloïn. Segue algumas características dessa camada de comunicação. Confiabilidade: Toda mensagem é entregue sem qualquer alteração. Interface simplificada: Esse serviço de comunicação é baseado na ideia de canais e provê uma interface básica envio/recepção. A camada Gimli provê uma API em nível de kernel sobre a qual todos os serviços do Kerrighed são executados, em especial o KerNet. A camada Gloin é responsável pela confiabilidade da comunicação (controle de erro, retransmissão de pacote, etc). 162

163 Conclusão do Capítulo Ao pesquisar sobre os modelos e tipos de clusters apresentados nesse capítulo, pudemos chegar a algumas conclusões preliminares que, no nosso juízo, deveriam ser registradas. Os sistemas de clusters que possuem um nó controlador, como, por exemplo, o Beowulf, são de desenvolvimento mais simples e usualmente, possuem uma melhor performance que os clusters SSI (Single System Image), porém a arquitetura física e lógica de um elemento que gerencia os nós escravos, sendo a única interface entre o ambiente externo e o cluster, produz uma condição intrínseca de um ponto único de falha, que faz desse modelo de processamento distribuído não aderente a ambientes de alta disponibilidade. Apesar de haver soluções de redundância para o nó mestre para clusters com essa característica, provendo assim uma maior robustez ao sistema como um todo, essa solução de contorno incide num custo maior na implementação do cluster, que vai de encontro com a nossa proposta de oferecer uma solução não dispendiosa dessa tecnologia. Quanto aos clusters SSI, vemos neles uma solução mais elegante e tecnicamente rica, pois se propõe a tornar um grupo de computadores numa única entidade, através de um sistema operacional que provê esse tipo de funcionalidade. Por certo, desenvolver um sistema dessa natureza é um desafio, pois como descrevemos nesse capítulo, trabalhar com elementos como threads, memória e espaço de memória e sockets num ambiente de sistema de imagem única, requer um maior grau de complexidade e consequentemente soluções mais apuradas para implementar tais funcionalidades, que já estão consolidadas em ambientes de processamento monoprocessado. Assim um sistema de cluster seja qual o modelo e tecnologia utilizada não será uma somatória simples do poder de processamento e funcionalidades dos nós que o compõe, pois uma boa parte dos recursos desses nós serão utilizados para o estabelecimento e a manutenção do cluster. 163

164 Capítulo 3 Apresentação do Laboratório A apresentação do laboratório considerará os seguintes aspectos: Descrição do hardware utilizado Descrição do Sistema Operacional utilizado Descrição da configuração do Cluster Kerrighed implementada Descrição dos aplicativos utilizados para análise do ambiente em cluster e standalone, de acordo com a proposta desse trabalho. Descrição do hardware utilizado Segue um esquema lógico do laboratório proposto: Figura

165 Segue uma imagem dos equipamentos do laboratório: Figura

166 Descrição dos itens que compõe o laboratório: Switch Catalyst 3750E 24 Portas 10/100/1000 e 2 Portas 10 Gigabit Ethernet Desempenho: Capacidade de switching fabric 160 Gbps Taxa de transmissão 65,5 Mpps Principais funcionalidades: IEEE 802.1s IEEE 802.1w IEEE 802.1x IEEE 802.3ad IEEE 802.3af IEEE 802.3x full duplex on 10BASE-T, 100BASE-TX e 1000BASE-T IEEE 802.1D Spanning Tree Protocol IEEE 802.1p CoS Prioritization IEEE 802.1Q VLAN IEEE BASE-T IEEE 802.3u 100BASE-TX IEEE 802.3ab 1000BASE-T IEEE 802.3z 1000BASE-X 100BASE-FX 1000BASE-T 1000BASE-SX 1000BASE-LX/LH 166

167 Computadores Para facilitar a identificação passaremos a designar os computadores utilizados no laboratório como Nó 00 e Nó 01 do cluster. Nó 00 Processador Intel(R) Core(TM)2 Duo CPU 2.93GHz Memória 2075 MB Sistema Operacional Debian GNU/Linux Controladora de Disco Intel Corporation 82801GB/GR/GH Disco ATA SAMSUNG HD322HJ Kernel Linux krg (i686) Interface de Rede 2 x Broadcom Corporation NetXtreme BCM5700 Gigabit Ethernet 167

168 Nó 01: Processador Intel(R) Core(TM)2 CPU 2.93GHz Memória 2334 MB Sistema Operacional Debian GNU/Linux Controladora de Disco Marvell Technology Group Ltd. 88SE6145 SATA II PCI-E controller Disco Seagate Barracuda ST340014A 40GB Kernel Linux krg (i686) Interface de Rede 2 x Broadcom Corporation NetXtreme BCM5700 Gigabit Ethernet Descrição do Sistema Operacional utilizado O Sistema Operacional utilizado é o Linux na distribuição Debian na versão do GNU/Linux com kernel modificado para suporte ao Kerrighed. A escolha da distribuição Debian deu-se por a mesma ter uma melhor compatibilidade com Kerrighed e especialmente na instalação do mesmo. O Debian também se mostrou muito estável e resiliente durante a implementação e testes do cluster. Seguem algumas características que contribuíram para escolha do Debian: É mantido por seus próprios usuários. Se alguma funcionalidade precisa ser aperfeiçoada, a própria comunidade atua na melhoria. Suporte eficiente pela própria comunidade. Mensagens enviadas às listas de discussão frequentemente são respondidas em cerca 15 minutos. 168

169 Pacotes bem integrados O Debian supera todas as outras distribuições no que se refere à qualidade de integração de seus pacotes. Já que todo software é organizado em grupos coerentes, não apenas pode-se encontrar todos os pacotes em um única fonte, mas pode-se assegurar de que já foram tratados os problemas no que tange às dependências complexas. Apesar de o formato deb ter algumas vantagens sobre o rpm, é a integração entre os pacotes que faz o sistema Debian mais robusto. Código fonte Quantidade significativa de ferramentas de desenvolvimento, facilitando a inclusão de funcionalidades ao sistema operacional. Estabilidade Os desenvolvedores do Debian afirmam que existe uma quantidade significativa de caso em que computadores executam a distribuição por um longo tempo, sem nenhuma indisponibilidade do sistema operacional. Pudemos verificar isso durante a implementação no laboratório. Rápido e leve com a memória Por ser baseado em GNU/Linux o Debian mostra-se confiável e leve no que concerne ao uso de memória. Drivers para a maioria do hardware são escritos pelos usuários de GNU/Linux, não pelos fabricantes. Embora se possa considerar como uma deficiência o tempo para que os novos dispositivos sejam suportados ou mesmo a falta de suporte para alguns deles, isso permite que o suporte ao hardware seja mantido até bem depois da parada de produção pelo fabricante ou da saída do mesmo do mercado. A experiência tem mostrado que drivers livres são normalmente melhores que os proprietários. 169

170 Descrição da configuração do Cluster Kerrighed implementada Histórico do Kerrighed O projeto Kerrighed foi iniciado por Christine Morin 19 em 1999 no INRIA, laboratório nacional francês para pesquisa em ciência da computação. Até 2006, o projeto foi desenvolvido no INRIA (Institut National de Recherche en Informatique et en Automatique) como protótipo de pesquisa com pessoas do INRIA, EDF e Universidade de Rennes 1. Desde 2006, o Kerrighed é o fruto do projeto na comunidade PARIS, desenvolvido pelo Kerlabs, INRIA, parceiros do consórcio XtreemOS e um número crescente de colaboradores. Instalação do Kerrighed O Kerrighed foi instalado em dois nós através das instruções publicadas em Basicamente os fontes do Kerrighed e do kernel são obtidos no GForge do INRIA, ambos são configurados e compilados. Os seguintes diretórios e arquivos precisam ser criados para que a instalação tenha sido exitosa: /boot/vmlinuz krg kernel do Kerrighed /boot/system.map Tabela de símbolos do kernel do Kerrighed /lib/modules/ krg Módulos do Kerrighed /etc/init.d/kerrighed Script de serviços do Kerrighed /etc/default/kerrighed Configuração de Serviços /usr/local/share/man Páginas Man /usr/local/bin/krgadm Ferramenta de administração do cluster /usr/local/bin/krgcapset Ferramenta verificação de funcionalidades /usr/local/bin/krgcr-run Ativação checkpoint/restart dos processos /usr/local/bin/migrate Ferramenta de migração de processos /usr/local/lib/libkerrighed-* Biblioteca do Kerrighed /usr/local/include/kerrighed Cabeçalhos da Biblioteca do Kerrighed Tabela 1 Depois da instalação basta editar o arquivo /etc/kerrighed.nodes para identificar ou ativar os nós dentro do cluster automaticamente no momento da inicialização. 19 Cientista Sênior do Rennes - Bretagne Atlantique. Líder do grupo de pesquisa Myriads. Cofundadora do Kerlabs empresa criada para fornecer serviços comerciais na tecnologia Kerrighed. Coordenadora científica do projeto europeu do XtreemOS. 170

171 O Kerrighed cria uma nova imagem de sistema que pode ser escolhida no momento da inicialização do Linux. Com o comando krgadm o cluster pode ser inicializado manualmente, podendo-se verificar se o mesmo está funcional e reconhecendo os nós. Descrição dos aplicativos para testes PovRay Uma atividade computacional intensa é a criação de imagens em três dimensões em computadores. As empresas cinematográficas têm usado cada vez mais esse recurso, seja para criar produções totalmente animadas digitalmente, seja para criar alguma imagem que seria dispendiosa ou mesmo impossível de ser gerada, utilizando a criação tradicional de cenários. Apesar dos sistemas em cluster em geral não serem, via de regra, apropriados para execução aplicações em tempo real, como por exemplo, VoD ou IPTV, eles são muito utilizados nos processos de renderização de imagens, pois os mesmos necessitam de sistemas de grande poder de computação que podem ser provido pelos clusters. Iremos verificar se o Kerrighed apresenta bons resultados utilizando a aplicação de renderização de imagens PovRay (Persistence of Vision Ray Tracer) que é uma ferramenta com recursos interessantes, com uma baixa complexidade no manuseio e apresentando imagens de ótima qualidade em termos de cores, detalhes e iluminação, muito próximas de imagens reais. O ray-tracing é um método de gerar imagens a partir de uma descrição geométrica de objetos. Ele é uma técnica de renderização que calcula uma imagem de alguma cena através da simulação de raios de luz que viajam no mundo real. Entretanto esse trabalho é feito de trás para frente. No mundo real a luz é emitida de uma fonte e ilumina os objetos. A luz reflete nos objetos e passa através de objetos transparentes. Essa luz refletida atinge nossos olhos ou a lente de uma câmera, por exemplo. Como a vasta maioria dos raios nunca atinge um observador, gerar uma cena desse modo levaria um enorme tempo. 171

172 Programas como o PovRay simulam os raios de luz saindo por detrás da cena. O usuário especifica a localização da câmera, as fontes de luz, os objetos, a textura das superfícies dos mesmos, seu interior (caso forem transparentes) e qualquer atmosfera como neblina, bruma ou fogo. Para cada pixel da imagem final, um ou mais raios visíveis são disparados da câmera na cena, para verificar se eles interceptam algum objeto na mesma. Esses raios visíveis originados pelo observador, representados por uma câmera, passam através de um espaço visível, gerando a imagem final. Em cada momento que um objeto é atingido, a cor da superfície do mesmo é calculada. Por esse motivo raios são enviados de trás para frente, de cada fonte luz para determinar a quantidade de luminosidade vinda dessas fontes. Raios representando sombras são gerados para determinar se o ponto está nas sombras ou não. Se a superfície é reflexiva ou transparente, novos raios são configurados e traçados para determinar a contribuição de luz refletida e refratada para cor final da superfície. Para funcionalidades especiais como reflexão interdifusa, efeitos atmosféricos e áreas de luz, faz-se necessário disparar um número maior de raios na cena para cada pixel. Uma das verificações que serão realizadas no laboratório será a renderização de uma imagem e o consumo de tempo e recursos para realizar esse tipo de operação computacional. Naturalmente existem outros métodos e ferramentas para renderização de imagens. Podemos mencionar como métodos rasterization e ray casting e como ferramentas Mental Ray e RenderMan. Segundo os desenvolvedores do PovRay a versão 3.7 (Beta) já suporta de maneira nativa processamento paralelo. Iniciaremos o nosso laboratório com a versão 3.6 por ser a versão oficialmente consolidada. Após fazer um download do arquivo binário do PovRay em basta seguir as instruções para instalação apresentada no mesmo WEB site. 172

173 Breve: Um ambiente 3D para Simulação de Sistemas Descentralizados e Vida Artificial O Breve é um ambiente em 3D destinado a simulação de sistemas descentralizados e de vida artificial. Enquanto ele é conceitualmente similar aos sistemas já existentes tais como o Swarn e o StarLogo, sua implementação, que simula tanto tempo contínuo e espaço contínuo em 3D, é significamente diferente dos sistemas citados, tanto que o ambiente do Breve é adequado para diferentes classes de simulações. O Breve inclui uma linguagem interpretada orientada a objeto, a OpenGL, dispositivo de detenção de colisão, suporte experimental para corpos físicos articulados e resolução de colisão com fricção estática e dinâmica. O principal objetivo desse sistema é permitir a implementação rápida e fácil de simulações descentralizadas ao mesmo tempo em que provê uma estrutura com muitos recursos que facilitam a construção de simulações de vida artificial avançadas. O Breve é um ambiente integrado de simulação o qual objetiva simplificar grandemente a implementação de sistemas descentralizados e simulações avançadas de vida artificial. Ele é destinado tanto para usuários que não programam como usuários com experiência em linguagem de programação, bibliotecas e programas. As simulações do Breve são escritas numa linguagem simplificada orientada a objeto chamada steve. A linguagem steve, especialmente designada para simulações em 3D, incluem coletores de lixo (garbage collection), suporte a listas, vetores de 3D nativos assim como grupo de classes que fazem interface com funcionalidades de simulação do sistema central (engine) do Breve. Ele também oferece uma arquitetura de plugin simples com a qual os usuários podem estabelecer interfaces com bibliotecas externas ou linguagens, acessando as mesmas através do steve. O steve é uma linguagem procedural e muitas de suas funcionalidades parecerão familiar aos usuários da linguagem C. A diferença é que a sintaxe do método de chamadas é mais parecida com o Objetive-C. No steve, cada argumento de um método de chamada é associado a uma palavra chave. Isso significa que os argumentos não são identificados por sua ordem, mas por suas palavras chaves. O fato de steve ser uma linguagem interpretada que retém muitos tipos de verificações e métodos de busca até o momento da execução do código, pode causar algum problema de desempenho, mas na prática, os gargalos das simulações do Breve estão mais relacionadas a simulação física e a renderização das imagens do que na execução do código do steve. 173

174 Classes hierárquicas gerais A interação com as funcionalidades nativas do Breve é realizada da através de classes hierárquicas gerais. No topo dessa hierarquia temos a classe chamada Object que é o pai de todos os objetos criados no Breve. A hierarquia é dividida em classe Abstract e classe Real. A classe Abstract é definida como classes que não possuem uma representação física no mundo simulado, enquanto a classe Real está associada a alguns tipos de objetos físicos. A classe Real inclui objetos móveis e os objetos estacionários. As funções dessas classes são simples: objetos móveis representam agentes que se movem durante o curso da simulação, enquanto os objetos estacionários representam entidades que são imóveis durante o curso da simulação, tais como o piso e obstáculos. Os membros mais importantes da hierarquia Abstract são as classes Control e Data. A primeira que provê uma interface com o engine do Breve, controlando funcionalidades como câmera, ajuste de luminosidade, renderização gráfica e interface com usuário. A classe Data é uma classe especial pode ser salva em disco ou em rede. Eventos e Escalonamento O comportamento dos agentes são escritos no steve como parte da definição de um objeto. Cada ação que o agente pode tomar pode ser escrita como um método separado que é chamado em resposta a certos eventos. Há muitos modos de disparar eventos dentro de uma simulação no Breve: Eventos chamados por interação Eventos escalonados para um momento específico Eventos disparados por notificações Eventos disparados por colisões Eventos disparados através da interface de usuário 174

175 Init e Destroy Se necessário, os métodos especiais init e destroy são automaticamente chamados, por exemplo, quando uma instância é criada e liberada, respectivamente. Assim esse método permite manipular inicialização e a desativação de uma instância, se necessário. Execução de Simulações Cada simulação é controlada por um simples objeto controlador uma instância da classe nativa Control (ou algumas de suas subclasses). A instância controladora é definida no código fonte da simulação, sendo a única instância que é automaticamente criada quando uma simulação é executada. Outras instâncias podem, por sua vez, serem criadas pela instância controladora através do método init. A instância controladora também recebe um número de retornos (callbacks) de objetos no mundo simulado ou selecionando itens de um menu, assim nesse caso, a instância controladora pode ser considerada como o processo principal da simulação. Concluindo, o ambiente de simulação Breve é único, sendo adequado para simulações de vida artificial e outros sistemas descentralizados. Sua principal ênfase é estabelecer como objetivo a implementação de simulações de baixo nível altamente realistas a fim de manipular comportamentos de alto nível com o mesmo grau de realidade. As funcionalidades como a habilidade de simular e apresentar modelos de 3D contínuo, facilidade de uso de sua linguagem orientada a objeto, assim como a sua capacidade para realização de simulação física, distingue o Breve dos pacotes de simulação atuais. Quanto ao processamento paralelo não existe nenhuma informação dos desenvolvedores da aplicação sobre o tema, mas o OpenGL que realiza grande parte das funções do Breve provê suporte para processamento paralelo, assim inferimos que o mesmo seja beneficiado com esse modelo computacional. O software Breve pode ser obtido em 175

176 Conclusão do capítulo Apesar do ambiente provido para a medições e análise ser de natureza singela em termos de quantidade de nós do cluster e das aplicações que serão utilizadas no laboratório, acreditamos que o objetivo desse trabalho será alcançados tendo em vista que a proposição é avaliar aplicação de Design Digital, no caso o PovRay e Inteligência Artificial, o Breve num ambiente de cluster. Certamente outras aplicações de mesma natureza terão comportamento e desempenho distintos, especialmente no que tange a utilização dos recursos do processamento paralelo. É importante ressaltar que o próprio cluster e suas funcionalidades inerentes podem também influenciar nos resultados obtidos. Acreditamos que a análise nesse ambiente mais restrito, facilitará as medições, comparações e conclusões e ao mesmo tempo servirá de arcabouço para uma abordagem mais abrangente do tema, realizando testes com outras aplicações e em condições distintas, como por exemplo, um cluster com um número maior de nós. 176

177 Capítulo 4 Medições e análises Os sistemas em clusters serão mais plenamente aproveitados se as aplicações que forem executadas pelos mesmos suportarem processamento paralelo que seria dividir tarefas e funções da aplicação entre os processadores que os compõe. Em sistemas paralelos as principais métricas são ganho de velocidade (speedup) e a capacidade de crescimento ou escalabilidade, visando sempre executar as aplicações num tempo menor, se estamos tratando de HPC (High Performance computing). Quando falamos de escalabilidade estamos considerando o quanto uma determinada aplicação será beneficiada com o aumento de nós num cluster, pois na maioria dos casos existe um ponto de saturação, quando a inserção de um novo nó no cluster passa a não corresponder a um aumento de desempenho. De fato, podemos ter casos em que o aumento de nós pode vir a degradar o desempenho da aplicação. Essa resposta em termos de desempenho dependerá de parâmetros como velocidade de clock, tamanho do problema (granularidade), tempo de utilização de CPU, uso do canal de comunicação, demanda por operações de memória e E/S, dentre outros itens. Existem diversas abordagens e componentes para avaliação de desempenho de clusters, analisaremos algumas delas: Performance teórica de pico Esse valor representa o máximo de operações em ponto-flutuante por segundo, calculado pela seguinte fórmula: P=N * C* F * R Fórmula 2 Onde: P representa o desempenho medido em Mflops ou Gflops N é o número de nós do cluster C identifica o número de CPU s por nó F é o número de operações em ponto-flutuante por ciclos de clock R é a velocidade de clock medido em ciclos por segundo 177

178 Performance das Aplicações É o número de operações realizadas quando se está executando uma determinada aplicação, dividido pelo tempo de execução. Esse tipo de medida é feita através de programas de benchmark não correspondendo pelo menos em sua plenitude a uma aplicação de uso prático. Execução de Aplicações Seria a medição do tempo de execução de determinada aplicação numa condição predeterminada. No nosso caso utilizaremos essa abordagem ao analisar o PovRay. Ganho de velocidade Podemos medir o ganho de velocidade de uma determinada aplicação num cluster comparando o seu tempo de execução com tempo de execução da mesma aplicação num computador standalone. Segue a fórmula: Fórmula 3 Lei de Amdahl 20 A programação de aplicações que utilizem o processamento paralelo ainda está num estágio incipiente, assim existem aplicações que apenas parte das tarefas é executada paralelamente e algumas em que as tarefas são totalmente serializadas. Amdahl criou uma expressão para medir a porção de processamento paralelo e a porção de processamento serializado numa dada aplicação. 20 Gene Myron Amdahl (16 de novembro de 1922) é um projetista de computadores e empreendedor no ramo da alta tecnologia, mais conhecido por seu trabalho com mainframes na International Business Machines (IBM) e posteriormente por suas próprias empresas, particularmente a Amdahl Corporation. Ele talvez seja mais lembrado por ter formulado a Lei de Amdahl, uma teoria fundamental da computação paralela. 178

179 A fórmula é trivial: Fórmula 4 Onde: p representa o desempenho da porção serial em porcentagem T é o tempo em segundos (1-p) representa a porção paralelizável N é o número dos nós do cluster Somente a porção paralelizável do programa que se beneficia com os processadores dos nós do cluster. Assim o ganho de processamento seria: Fórmula 5 Quanto mais a aplicação tiver tarefas que são processadas de modo paralelizado e quanto maior a quantidade de nós no cluster, maior será o ganho de processamento segundo Amdahl. Performance da rede As conexões de rede são também um item essencial no desempenho do cluster como um todo. Seguem alguns quesitos importantes no que tange às redes que conectam os nós que compõe um cluster: 179

180 Vazão (throughput): A quantidade efetiva de dados em bits por segundo que são transmitidos entre os nós. Apesar velocidade das interfaces de rede e do elemento onde elas estão conectadas (usualmente um switch) serem determinantes para o desempenho da rede, existem outros fatores que precisam ser considerados como, por exemplo, o desempenho dos nós em geral em termos de CPU, memória, cache, etc, assim como o barramento em que estão conectadas as interfaces de rede, os drivers dessas interface e latência do sistema como um todo, dentre de outros fatores. Eficiência do protocolo TCP-IP: O protocolo TCP-IP comporta-se de maneira diferente em relação aos diferentes aplicativos e os parâmetros que o mesmo utiliza. Por exemplo, o protocolo NFS (Network File System) tende a ter uma melhor performance que o CIFS (Common Internet File System) em condições normais, sem nenhum ajuste de parâmetros de TCP-IP nesses aplicativos. Overhead do TCP-IP e das camadas de rede inferiores: Existem uma quantidade significativa da banda das conexões de rede que são utilizadas para endereçamento, multiplexação, detecção e correção de erros que não será efetivamente utilizada para o tráfego de dados e manutenção do cluster. Esse overhead impede de utilizarmos capacidade total de banda disponível para tráfego efetivo de dados. Abordagem e ferramentas de análise do desempenho do cluster A nossa abordagem e estratégia de medição da performance será a seguinte: Medição e análise do throughput real das conexões de rede. Estresse do cluster e análise, para confirmar a efetiva funcionalidade do mesmo. Teste e medição de memória. Medição e análise do sistema em cluster e monoprocessado em ferramentas tradicionais de benchmark apresentadas no aplicativo hardinfo. Medição e análise do sistema monoprocessado e em cluster utilizando um aplicativo de Design Digital (PovRay). Medição e análise do sistema monoprocessado e em cluster utilizando um aplicativo de Inteligência Artificial (Breve). 180

181 Análise geral dos resultados Medição e análise do throughput real das conexões de rede. Utilizamos o aplicativo iperf para medir o throughput real das conexões de rede e como esperado não foi alcançada a banda passante de 1 Gigabits/sec que é a velocidade das interfaces de redes, pelos motivos explanados no início desse capítulo. Seguem as medições: Figura 20 Percebemos que na transmissão unidirecional de pacotes obtemos a taxa de 644 Mbits/sec, 64% da banda nominal das interfaces de rede que são de 1 Gigabit Ethernet. Na transmissão bi-direcional obtemos os valores de 279 Mbits/sec num sentido e 411 Mbits/sec no outro. Isso é um indicativo que um dos computadores tem um melhor throughput, que seria aquele que tem uma configuração de hardware superior, que confirma o fato que esse quesito pode ser determinante na taxa de transferência de um sistema. 181

182 Consideramos uma taxa de transferência de 644 Mbits/sec adequada para um cluster com apenas dois nós, não sendo um impedimento para a utilização plena do mesmo. Essa afirmação será verificada nas próximas medições e análises. Estresse do cluster e análise para confirmar a efetiva funcionalidade do mesmo Para verificar o comportamento do cluster numa situação de estresse, estabelecemos o seguinte cenário: Nó 00 Aplicações executadas: Breve Creature.tz PovRay benchmark.pov Nó 01 Aplicação executada: Breve Gatherers.tz PovRay benchmark.pov Utilizaremos a aplicação system monitor para medir a utilização de CPU, memória e consumo de banda do cluster. 182

183 Telas Nó 00: Figura 21 Execução das aplicações Breve e PovRay no Nó 00 Figura 22 Evidência de o cluster estar operacional 183

184 Figura 23 Medições de utilização CPU, Memória e Rede no Nó 00 Figura 24 Tempo de renderização do Benchmark.pov no Nó

185 Tela Nó 01 Figura 25 Execução da aplicação Breve no Nó 01 Figura 26 Tempo de renderização do Benchmark.pov no Nó

186 Percebemos que apenas quando iniciamos a execução da renderização do arquivo benchmark.pov que a utilização de CPU em ambos os computadores chegou a 100%, porém a utilização de memória e o consumo de banda se mantiveram estáveis e em níveis baixos. Podemos afirmar nessa primeira análise que a renderização de imagens pelo menos em se tratando do PovRay possui uma tendência para utilização intensa de CPU. O tempo total de renderização do arquivo Benchmark.pov no nó 01 foi de 3 minutos e 58 segundos numa condição de saturação das CPU s. A título de esclarecimento, como os processadores dos nós são Core Duo, os mesmos são apresentados como 4 processadores pelo system monitor. Podemos também afirmar que nas condições de testes estabelecidas o consumo de banda foi muito baixo, como uma sinalização que esse componente não será um fator de estrangulamento no ambiente proposto. Pela utilização consideravelmente baixa de memória durante a execução dos aplicativos no teste de estresse proposto, decidimos fazer um teste específico de memória para verificar o comportamento desse componente num cluster Kerrighed. Teste e medição de memória Utilizamos o aplicativo memtester para verificar as condições da memória do cluster, pois o seu uso durante a execução das aplicações PovRay e Breve foi muito reduzido. Esse aplicativo destina-se a verificar a integridade de memória RAM em Linux, realizando uma série de verificações. O comportamento do cluster Kerrighed nesse teste foi positivo, tendo em vista que o compartilhamento e a integridade da memória num cluster, uma DSM (Distributed Shared Memory), é um dos grandes desafios dessa tecnologia. Porém não foi possível utilizar 4.6 Gbytes nesse teste, apenas 2.4 Gbytes. Ao ultrapassarmos esse limite o cluster deixa de operar, necessitando-se uma reinicialização do mesmo. Seguem os resultados. 186

187 Telas Nó 01: Figura 26 Medição do uso da memória durante a execução do memtester Figura 27 Finalização do teste de memória sem apresentar nenhum erro 187

188 Tela Nó 00: Figura 28 Medição do uso da memória durante a execução do memtester Concluímos em primeiro lugar que o cluster Kerrighed realiza a agregação das memórias físicas dos nós que o compõe. Temos o nó 00 com MBytes de memória e o nó 01 com o MBytes e o system monitor indicou uma memória total de cerca MBytes (4.6 Gbytes). Esse agregado de memória passou pelos testes do memtester sem apresentar nenhum erro, indicando consumo de memória configurado ao executar-se o comando, que foi de 2.3 Gbytes. Assim podemos concluir que as aplicações PovRay e Breve nas condições em que foi realizado o teste de estresse do cluster realmente não demandam uma quantidade de memória significativa. Outra observação foi novamente a utilização baixíssima dos recursos de rede, em torno de 10 Kbps. Medição e análise do sistema em cluster e nos nós com ferramentas de benchmark apresentadas no aplicativo hardinfo Executamos as rotinas de benchmark do aplicativo hardinfo em cada nó separadamente e no próprio cluster, seguem os resultados: 188

189 Gráfico 1 O valor maior indica um melhor desempenho. Gráfico 2 Menor valor indica um melhor desempenho. Gráfico 3 Maior valor indica um melhor desempenho. 189

190 Gráfico 4 Maior valor indica um melhor desempenho. Gráfico 5 Menor valor indica um melhor desempenho. Gráfico 6 Menor valor indica melhor desempenho. 190

191 Segue uma breve descrição dos testes de benchmark realizado pelo hardinfo: CPU Zlib - compressão de dados utilizando o algoritmo Zlib em 64 MBytes de dados. CPU Fibonacci - cálculo do número 42 de Fibonacci. CPU MD5 - Geração de hashing em MD5 para 312MB de dados. CPU SHA1- Geração de hashing em SHA1 para 312MB de dados. CPU Blowfish Execução do algoritmo de criptografia Blowfish FPU Raytracing Programa para renderização de imagens utilizando a mesma técnica do PovRay. Constatamos, mediante os valores levantados, que o desempenho do cluster é menor (apesar de ser muito próximo) ao desempenho do Nó 00 que é computador com a maior capacidade no cluster, pelo menos nas aplicações utilizadas no benchmark do hardinfo. Baseado nessas informações, podemos afirmar que o cluster SSI Kerrighed não seria uma infraestrutura viável pelo menos no que concerne ao desempenho, para os testes realizados pela aplicação hardinfo. Ao discutir com a comunidade do Kerrighed o resultado dos testes realizados até esse momento do nosso trabalho, os profissionais ou pesquisadores (dentre eles profissionais da Kerlabs) que contribuíram com suas experiências com o cluster Kerrighed, elencaram as seguintes considerações: Apenas aplicações desenvolvidas para processamento paralelo irão se beneficiar em termos de desempenho ao utilizarem o Kerrighed. O Kerrighed irá apenas apresentar resultados práticos significativos quando executarmos vários processos simultaneamente em todos os nós que compõe o cluster. Quanto ao memtester, um dos pesquisadores disse que ao fazer testes em memórias non-ecc utilizando essa ferramenta em nós individuais de seu cluster, como o memtester faz um locking de memória no espaço de usuário, ele não conseguiu testar toda a extensão da memória RAM. Ele sugeriu executar o memtester em todos os nós que compõe o cluster simultaneamente. 191

192 Para obtermos uma constatação definitiva da viabilidade do cluster Kerrighed, dentro das premissas propostas em nosso trabalho, como uma opção para o processamento de aplicações de Inteligência e Design Digital, no nosso caso o Breve e o PovRay, executaremos essas aplicações em ambiente standalone, verificando o comportamento das mesmas em relação ao ambiente em cluster, considerando os resultados e conhecimento adquiridos através dos testes e medições realizadas até esse estágio do trabalho. Medição e análise do sistema em cluster e monoprocessado utilizando um aplicativo de Design Digital (PovRay) Medir o desempenho do aplicativo PovRay foi relativamente simples, pois o mesmo apresenta o tempo de execução, ao finalizar uma renderização. Assim executamos o arquivo benchmark.pov em cada nó cluster em separado, executando o mesmo arquivo com cluster em operação. Executamos num primeiro momento o arquivo benchmark.pov em apenas um nó do cluster, após isso, executamos simultaneamente o arquivo nos dois nós que compõe o mesmo. Utilizamos o menor tempo de execução da renderização entre os dois nós como referência nessa medição. Algo digno de nota ao realizarmos a execução do arquivo benchmark.pov em apenas um nó do cluster, foi que o shell (terminal) foi aberto e executado num nó do cluster e a imagem renderizada surgiu no outro nó que compõe o mesmo, comprovando a capacidade do cluster de migrar processos Tempo de execução do benchmark.pov em segundos 0 Nó 00 Nó 01 Execução em 1 Nó Execução em 2 Nós Execução em 2 Nós com alta Utilização Gráfico 7 192

193 Constatamos que o tempo de execução do arquivo do PovRay é maior para cluster do que para o computador standalone com maior poder computacional que compõe o mesmo. Percebemos também, que ao executarmos o arquivo benchmark.pov concorrentemente nos dois nós, houve uma diminuição do tempo de execução, confirmando a tese que o cluster Kerrighed apresenta um melhor desempenho quando executamos vários processos simultâneos. Para reforçar a validade dessa hipótese, executamos em ambos os nós a simulação do Breve Gatherers.tz, assim como o benchmark.pov. O desempenho do Kerrighed, ao executar esses processos simultaneamente, melhorou significantemente, atingindo o mesmo tempo do execução do computador com melhor hardware que compõe o cluster. Porém em nenhum momento o Kerrighed obteve um melhor desempenho que o nó com a melhor configuração de hardware executando o mesmo arquivo do PovRay, trabalhando em modo standalone. Concluímos que o cluster Kerrighed executando renderizações na aplicação PovRay, não provê um aumento de desempenho linearmente proporcional a quantidade de nós que compõe o cluster, mas apenas nos beneficiamos dos recursos do Kerrighed quando executamos vários processos ao mesmo tempo, podendo assim renderizar vários arquivos numa mesma plataforma virtual de hardware. Ao também discutirmos o tema com Marcos Pitanga, um dos profissionais especializados em cluster Linux no Brasil, autor de livros abordando essa tecnologia, o mesmo também confirmou que clusters SSI (Single System Image), realmente teriam esse comportamento, de utilizarem todos os recursos de um nó, até que os mesmos sejam exauridos, para que utilizem os recursos dos outros nós que compõe o cluster. 193

194 Medição e análise do sistema em cluster e monoprocessado utilizando um aplicativo de Inteligência Artificial (Breve) A comparação entre o sistema em cluster e um nó que compõe o mesmo em modo standalone, utilizando o Breve, não foi tão direta e simples como a abordagem utilizada com o PovRay, pois as simulações do Breve são de execução contínua. Assim a proposta para essa avaliação foi baseada na medição do consumo de processador e memória RAM que cada instância do Breve consumiria no ambiente monoprocessado e em cluster, e por extrapolação verificar o aumento de capacidade de execução de simulações baseadas em IA realizadas pelo Breve no cluster. Ao iniciar os testes e medições, percebeu-se que como o Breve gera imagens em movimento no ambiente gráfico do Linux (GNOME), muito do processamento era consumido por esse processo como se pode verificar no resultado do comando ps -eo pmem,pcpu,args sort -k 1 -r less abaixo: Figura 29 - Resultado do comando ps em ambiente monoprocessado Figura 30 - Resultado do comando ps em cluster 194

Sistemas Distribuídos

Sistemas Distribuídos Sistemas Distribuídos Modelo Cliente-Servidor: Introdução aos tipos de servidores e clientes Prof. MSc. Hugo Souza Iniciando o módulo 03 da primeira unidade, iremos abordar sobre o Modelo Cliente-Servidor

Leia mais

Faculdades Santa Cruz - Inove. Plano de Aula Base: Livro - Distributed Systems Professor: Jean Louis de Oliveira.

Faculdades Santa Cruz - Inove. Plano de Aula Base: Livro - Distributed Systems Professor: Jean Louis de Oliveira. Período letivo: 4 Semestre. Quinzena: 5ª. Faculdades Santa Cruz - Inove Plano de Aula Base: Livro - Distributed Systems Professor: Jean Louis de Oliveira. Unidade Curricular Sistemas Distribuídos Processos

Leia mais

Sistemas Operacionais

Sistemas Operacionais Sistemas Operacionais Aula 6 Estrutura de Sistemas Operacionais Prof.: Edilberto M. Silva http://www.edilms.eti.br Baseado no material disponibilizado por: SO - Prof. Edilberto Silva Prof. José Juan Espantoso

Leia mais

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO Conceitos básicos e serviços do Sistema Operacional Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO Tipos de serviço do S.O. O S.O.

Leia mais

} Monolíticas Aplicações em um computador centralizado. } Em Rede Aplicações com comunicação em rede. } Distribuídas Comunicação e cooperação em rede

} Monolíticas Aplicações em um computador centralizado. } Em Rede Aplicações com comunicação em rede. } Distribuídas Comunicação e cooperação em rede Prof. Samuel Souza } Monolíticas Aplicações em um computador centralizado } Em Rede Aplicações com comunicação em rede } Distribuídas Comunicação e cooperação em rede } Aplicações que são funcionalmente

Leia mais

Infra-Estrutura de Software. Introdução. (cont.)

Infra-Estrutura de Software. Introdução. (cont.) Infra-Estrutura de Software Introdução (cont.) O que vimos Complexidade do computador moderno, do ponto de vista do hardware Necessidade de abstrações software Sistema computacional em camadas SO como

Leia mais

Processos e Threads (partes I e II)

Processos e Threads (partes I e II) Processos e Threads (partes I e II) 1) O que é um processo? É qualquer aplicação executada no processador. Exe: Bloco de notas, ler um dado de um disco, mostrar um texto na tela. Um processo é um programa

Leia mais

1 http://www.google.com

1 http://www.google.com 1 Introdução A computação em grade se caracteriza pelo uso de recursos computacionais distribuídos em várias redes. Os diversos nós contribuem com capacidade de processamento, armazenamento de dados ou

Leia mais

Introdução. O que vimos. Infraestrutura de Software. (cont.) História dos Sistemas Operacionais. O que vimos 12/03/2012. Primeira geração: 1945-1955

Introdução. O que vimos. Infraestrutura de Software. (cont.) História dos Sistemas Operacionais. O que vimos 12/03/2012. Primeira geração: 1945-1955 O que vimos Infraestrutura de Software Introdução (cont.) Complexidade do computador moderno, do ponto de vista do hardware Necessidade de abstrações software Sistema computacional em camadas SO como uma

Leia mais

Sistema Operacional Correção - Exercício de Revisão

Sistema Operacional Correção - Exercício de Revisão Prof. Kleber Rovai 1º TSI 22/03/2012 Sistema Operacional Correção - Exercício de Revisão 1. Como seria utilizar um computador sem um sistema operacional? Quais são suas duas principais funções? Não funcionaria.

Leia mais

IFPE. Disciplina: Sistemas Operacionais. Prof. Anderson Luiz Moreira

IFPE. Disciplina: Sistemas Operacionais. Prof. Anderson Luiz Moreira IFPE Disciplina: Sistemas Operacionais Prof. Anderson Luiz Moreira SERVIÇOS OFERECIDOS PELOS SOS 1 Introdução O SO é formado por um conjunto de rotinas (procedimentos) que oferecem serviços aos usuários

Leia mais

SISTEMAS DISTRIBUIDOS

SISTEMAS DISTRIBUIDOS 1 2 Caracterização de Sistemas Distribuídos: Os sistemas distribuídos estão em toda parte. A Internet permite que usuários de todo o mundo acessem seus serviços onde quer que possam estar. Cada organização

Leia mais

Sistemas Operacionais. Conceitos de um Sistema Operacional

Sistemas Operacionais. Conceitos de um Sistema Operacional Sistemas Operacionais Conceitos de um Sistema Operacional Modo usuário e Modo Kernel Como já vimos são ambientes de execução diferentes no processador Há um conjunto de funções privilegiadas acessadas

Leia mais

Resumo até aqui. Gerenciamento Proteção Compartilhamento. Infra-estrutura de Software

Resumo até aqui. Gerenciamento Proteção Compartilhamento. Infra-estrutura de Software Resumo até aqui Complexidade do computador moderno, do ponto de vista do hardware Necessidade de abstrações software Sistema computacional em camadas SO como uma máquina estendida abstrações SO como um

Leia mais

SISTEMAS OPERACIONAIS

SISTEMAS OPERACIONAIS SISTEMAS OPERACIONAIS Turma de Redes AULA 06 www.eduardosilvestri.com.br silvestri@eduardosilvestri.com.br Estrutura do Sistema Operacional Introdução É bastante complexo a estrutura de um sistema operacional,

Leia mais

Sistemas Distribuídos Capítulos 3 e 4 - Aula 4

Sistemas Distribuídos Capítulos 3 e 4 - Aula 4 Sistemas Distribuídos Capítulos 3 e 4 - Aula 4 Aula passada Threads Threads em SDs Processos Clientes Processos Servidores Aula de hoje Clusters de Servidores Migração de Código Comunicação (Cap. 4) Fundamentos

Leia mais

Profs. Deja e Andrei

Profs. Deja e Andrei Disciplina Sistemas Distribuídos e de Tempo Real Profs. Deja e Andrei Sistemas Distribuídos 1 Conceitos e Projetos de Sistemas Distribuídos Objetivos: Apresentar uma visão geral de processamento distribuído,

Leia mais

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2 SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2 1.1 Introdução... 2 1.2 Estrutura do IP... 3 1.3 Tipos de IP... 3 1.4 Classes de IP... 4 1.5 Máscara de Sub-Rede... 6 1.6 Atribuindo um IP ao computador... 7 2

Leia mais

Redes de Computadores. Prof. André Y. Kusumoto andre_unip@kusumoto.com.br

Redes de Computadores. Prof. André Y. Kusumoto andre_unip@kusumoto.com.br Redes de Computadores Prof. André Y. Kusumoto andre_unip@kusumoto.com.br Open Systems Interconnection Modelo OSI No início da utilização das redes de computadores, as tecnologias utilizadas para a comunicação

Leia mais

Um Driver NDIS Para Interceptação de Datagramas IP

Um Driver NDIS Para Interceptação de Datagramas IP Um Driver NDIS Para Interceptação de Datagramas IP Paulo Fernando da Silva psilva@senior.com.br Sérgio Stringari stringari@furb.br Resumo. Este artigo apresenta o desenvolvimento de um driver NDIS 1 para

Leia mais

BACHARELADO EM SISTEMAS DE INFORMAÇÃO EaD UAB/UFSCar Sistemas de Informação - prof. Dr. Hélio Crestana Guardia

BACHARELADO EM SISTEMAS DE INFORMAÇÃO EaD UAB/UFSCar Sistemas de Informação - prof. Dr. Hélio Crestana Guardia O Sistema Operacional que você usa é multitasking? Por multitasking, entende-se a capacidade do SO de ter mais de um processos em execução ao mesmo tempo. É claro que, num dado instante, o número de processos

Leia mais

4 Estrutura do Sistema Operacional. 4.1 - Kernel

4 Estrutura do Sistema Operacional. 4.1 - Kernel 1 4 Estrutura do Sistema Operacional 4.1 - Kernel O kernel é o núcleo do sistema operacional, sendo responsável direto por controlar tudo ao seu redor. Desde os dispositivos usuais, como unidades de disco,

Leia mais

Arquitetura dos Sistemas de Informação Distribuídos

Arquitetura dos Sistemas de Informação Distribuídos Arquitetura dos Sistemas de Informação Distribuídos Quando se projeta um sistema cuja utilização é destinada a ser feita em ambientes do mundo real, projeções devem ser feitas para que o sistema possa

Leia mais

Sistemas Distribuídos. Professora: Ana Paula Couto DCC 064

Sistemas Distribuídos. Professora: Ana Paula Couto DCC 064 Sistemas Distribuídos Professora: Ana Paula Couto DCC 064 Questões Em uma rede de sobreposição (overlay), mensagens são roteadas de acordo com a topologia da sobreposição. Qual uma importante desvantagem

Leia mais

Capacidade = 512 x 300 x 20000 x 2 x 5 = 30.720.000.000 30,72 GB

Capacidade = 512 x 300 x 20000 x 2 x 5 = 30.720.000.000 30,72 GB Calculando a capacidade de disco: Capacidade = (# bytes/setor) x (méd. # setores/trilha) x (# trilhas/superfície) x (# superfícies/prato) x (# pratos/disco) Exemplo 01: 512 bytes/setor 300 setores/trilha

Leia mais

Sistemas Operacionais

Sistemas Operacionais Sistemas Operacionais O que se espera de um sistema de computação? Execução de programas de usuários Permitir a solução de problemas Sistema Operacional (SO) é um programa colocado entre o hardware do

Leia mais

Sistemas Distribuídos. Professora: Ana Paula Couto DCC 064

Sistemas Distribuídos. Professora: Ana Paula Couto DCC 064 Sistemas Distribuídos Professora: Ana Paula Couto DCC 064 Processos- Clientes, Servidores, Migração Capítulo 3 Agenda Clientes Interfaces de usuário em rede Sistema X Window Software do lado cliente para

Leia mais

Comparação SDs X Scs

Comparação SDs X Scs Prof. Alexandre Lima Sistemas Distribuídos Cap 9 1/7 Comparação SDs X Scs Distribuição inerente Economia Velocidade Confiabilidade Crescimento incremental Descrição Algumas aplicações envolvem máquinas

Leia mais

Entendendo como funciona o NAT

Entendendo como funciona o NAT Entendendo como funciona o NAT Vamos inicialmente entender exatamente qual a função do NAT e em que situações ele é indicado. O NAT surgiu como uma alternativa real para o problema de falta de endereços

Leia mais

Considerações no Projeto de Sistemas Cliente/Servidor

Considerações no Projeto de Sistemas Cliente/Servidor Cliente/Servidor Desenvolvimento de Sistemas Graça Bressan Graça Bressan/LARC 2000 1 Desenvolvimento de Sistemas Cliente/Servidor As metodologias clássicas, tradicional ou orientada a objeto, são aplicáveis

Leia mais

Sistemas Operativos. Threads. 3º ano - ESI e IGE (2011/2012) Engenheiro Anilton Silva Fernandes (afernandes@unipiaget.cv)

Sistemas Operativos. Threads. 3º ano - ESI e IGE (2011/2012) Engenheiro Anilton Silva Fernandes (afernandes@unipiaget.cv) Sistemas Operativos Threads 3º ano - ESI e IGE (2011/2012) Engenheiro Anilton Silva Fernandes (afernandes@unipiaget.cv) Dos Processos para os Threads O conceito de thread foi introduzido na tentativa de

Leia mais

Curso Tecnológico de Redes de Computadores 5º período Disciplina: Tecnologia WEB Professor: José Maurício S. Pinheiro V. 2009-2

Curso Tecnológico de Redes de Computadores 5º período Disciplina: Tecnologia WEB Professor: José Maurício S. Pinheiro V. 2009-2 Curso Tecnológico de Redes de Computadores 5º período Disciplina: Tecnologia WEB Professor: José Maurício S. Pinheiro V. 2009-2 Aula 1 Conceitos da Computação em Nuvem A computação em nuvem ou cloud computing

Leia mais

Arquitetura de Computadores. Introdução aos Sistemas Operacionais

Arquitetura de Computadores. Introdução aos Sistemas Operacionais Arquitetura de Computadores Introdução aos Sistemas Operacionais O que é um Sistema Operacional? Programa que atua como um intermediário entre um usuário do computador ou um programa e o hardware. Os 4

Leia mais

IMPLEMENTAÇÃO DE SOCKETS E THREADS NO DESENVOLVIMENTO DE SISTEMAS CLIENTE / SERVIDOR: UM ESTUDO EM VB.NET

IMPLEMENTAÇÃO DE SOCKETS E THREADS NO DESENVOLVIMENTO DE SISTEMAS CLIENTE / SERVIDOR: UM ESTUDO EM VB.NET 1 IMPLEMENTAÇÃO DE SOCKETS E THREADS NO DESENVOLVIMENTO DE SISTEMAS CLIENTE / SERVIDOR: UM ESTUDO EM VB.NET Daniel da Silva Carla E. de Castro Franco Diogo Florenzano Avelino daniel.silva1@ext.mpsa.com

Leia mais

Sistemas Operacionais. Roteiro. Hardware. Marcos Laureano

Sistemas Operacionais. Roteiro. Hardware. Marcos Laureano Sistemas Operacionais Marcos Laureano 1/25 Roteiro Estrutura de um sistema operacional Interrupções Proteção do núcleo Níveis de privilégio Chamadas de sistema 2/25 Mono-processadores atuais seguem um

Leia mais

Unidade 13: Paralelismo:

Unidade 13: Paralelismo: Arquitetura e Organização de Computadores 1 Unidade 13: Paralelismo: SMP e Processamento Vetorial Prof. Daniel Caetano Objetivo: Apresentar os conceitos fundamentais da arquitetura SMP e alguns detalhes

Leia mais

Everson Scherrer Borges João Paulo de Brito Gonçalves

Everson Scherrer Borges João Paulo de Brito Gonçalves Everson Scherrer Borges João Paulo de Brito Gonçalves 1 Tipos de Sistemas Operacionais Os tipos de sistemas operacionais e sua evolução estão relacionados diretamente com a evolução do hardware e das

Leia mais

SISTEMAS OPERACIONAIS. Apostila 01 Assunto: Tipos de Sistemas Operacionais UNIBAN

SISTEMAS OPERACIONAIS. Apostila 01 Assunto: Tipos de Sistemas Operacionais UNIBAN SISTEMAS OPERACIONAIS Apostila 01 Assunto: Tipos de Sistemas Operacionais UNIBAN 2.0 - INTRODUÇÃO Os tipos de sistemas operacionais e sua evolução estão intimamente relacionados com a evolução do hardware

Leia mais

Arquitetura de Rede de Computadores

Arquitetura de Rede de Computadores TCP/IP Roteamento Arquitetura de Rede de Prof. Pedro Neto Aracaju Sergipe - 2011 Ementa da Disciplina 4. Roteamento i. Máscara de Rede ii. Sub-Redes iii. Números Binários e Máscara de Sub-Rede iv. O Roteador

Leia mais

ESTUDO DE CASO WINDOWS VISTA

ESTUDO DE CASO WINDOWS VISTA ESTUDO DE CASO WINDOWS VISTA História Os sistemas operacionais da Microsoft para PCs desktop e portáteis e para servidores podem ser divididos em 3 famílias: MS-DOS Windows baseado em MS-DOS Windows baseado

Leia mais

REDES DE COMPUTADORES

REDES DE COMPUTADORES REDES DE COMPUTADORES 09/2013 Cap.3 Protocolo TCP e a Camada de Transporte 2 Esclarecimentos Esse material é de apoio para as aulas da disciplina e não substitui a leitura da bibliografia básica. Os professores

Leia mais

Disciplina: Introdução à Informática Profª Érica Barcelos

Disciplina: Introdução à Informática Profª Érica Barcelos Disciplina: Introdução à Informática Profª Érica Barcelos CAPÍTULO 4 1. ARQUITETURA DO COMPUTADOR- HARDWARE Todos os componentes físicos constituídos de circuitos eletrônicos interligados são chamados

Leia mais

Intranets. FERNANDO ALBUQUERQUE Departamento de Ciência da Computação Universidade de Brasília 1.INTRODUÇÃO

Intranets. FERNANDO ALBUQUERQUE Departamento de Ciência da Computação Universidade de Brasília 1.INTRODUÇÃO Intranets FERNANDO ALBUQUERQUE Departamento de Ciência da Computação Universidade de Brasília 1.INTRODUÇÃO As intranets são redes internas às organizações que usam as tecnologias utilizadas na rede mundial

Leia mais

Sistemas Operacionais. Prof. André Y. Kusumoto andrekusumoto.unip@gmail.com

Sistemas Operacionais. Prof. André Y. Kusumoto andrekusumoto.unip@gmail.com Sistemas Operacionais Prof. André Y. Kusumoto andrekusumoto.unip@gmail.com Estruturas de Sistemas Operacionais Um sistema operacional fornece o ambiente no qual os programas são executados. Internamente,

Leia mais

SISTEMAS OPERACIONAIS CAPÍTULO 3 CONCORRÊNCIA

SISTEMAS OPERACIONAIS CAPÍTULO 3 CONCORRÊNCIA SISTEMAS OPERACIONAIS CAPÍTULO 3 CONCORRÊNCIA 1. INTRODUÇÃO O conceito de concorrência é o princípio básico para o projeto e a implementação dos sistemas operacionais multiprogramáveis. O sistemas multiprogramáveis

Leia mais

Capítulo 8 - Aplicações em Redes

Capítulo 8 - Aplicações em Redes Capítulo 8 - Aplicações em Redes Prof. Othon Marcelo Nunes Batista Mestre em Informática 1 de 31 Roteiro Sistemas Operacionais em Rede Modelo Cliente-Servidor Modelo P2P (Peer-To-Peer) Aplicações e Protocolos

Leia mais

Sistemas Operacionais

Sistemas Operacionais Sistemas Operacionais Gerência de processos Controle e descrição de processos Edson Moreno edson.moreno@pucrs.br http://www.inf.pucrs.br/~emoreno Sumário Representação e controle de processos pelo SO Estrutura

Leia mais

3. Arquitetura Básica do Computador

3. Arquitetura Básica do Computador 3. Arquitetura Básica do Computador 3.1. Modelo de Von Neumann Dar-me-eis um grão de trigo pela primeira casa do tabuleiro; dois pela segunda, quatro pela terceira, oito pela quarta, e assim dobrando sucessivamente,

Leia mais

Programação com acesso a BD. Prof.: Clayton Maciel Costa clayton.maciel@ifrn.edu.br

Programação com acesso a BD. Prof.: Clayton Maciel Costa clayton.maciel@ifrn.edu.br Programação com acesso a BD Prof.: Clayton Maciel Costa clayton.maciel@ifrn.edu.br 1 Introdução BD desempenha papel crítico em todas as áreas em que computadores são utilizados: Banco: Depositar ou retirar

Leia mais

As principais características da abordagem de um banco de dados versus a abordagem de processamento de arquivos são as seguintes:

As principais características da abordagem de um banco de dados versus a abordagem de processamento de arquivos são as seguintes: SGBD Características do Emprego de Bancos de Dados As principais características da abordagem de um banco de dados versus a abordagem de processamento de arquivos são as seguintes: Natureza autodescritiva

Leia mais

FTIN Formação Técnica em Informática Módulo de Administração de Servidores de Rede AULA 02. Prof. Gabriel Silva

FTIN Formação Técnica em Informática Módulo de Administração de Servidores de Rede AULA 02. Prof. Gabriel Silva FTIN Formação Técnica em Informática Módulo de Administração de Servidores de Rede AULA 02 Prof. Gabriel Silva Temas da Aula de Hoje: Revisão da Aula 1. Redes LAN e WAN. Aprofundamento nos Serviços de

Leia mais

INFORMÁTICA FUNDAMENTOS DE INTERNET. Prof. Marcondes Ribeiro Lima

INFORMÁTICA FUNDAMENTOS DE INTERNET. Prof. Marcondes Ribeiro Lima INFORMÁTICA FUNDAMENTOS DE INTERNET Prof. Marcondes Ribeiro Lima Fundamentos de Internet O que é internet? Nome dado a rede mundial de computadores, na verdade a reunião de milhares de redes conectadas

Leia mais

Programação Concorrente Processos e Threads

Programação Concorrente Processos e Threads Programação Concorrente Processos e Threads Prof. Eduardo Alchieri Processos O conceito mais central em qualquer sistema operacional é o processo Uma abstração de um programa em execução Um programa por

Leia mais

Redes de Computadores. Protocolos de comunicação: TCP, UDP

Redes de Computadores. Protocolos de comunicação: TCP, UDP Redes de Computadores Protocolos de comunicação: TCP, UDP Introdução ao TCP/IP Transmission Control Protocol/ Internet Protocol (TCP/IP) é um conjunto de protocolos de comunicação utilizados para a troca

Leia mais

http://aurelio.net/vim/vim-basico.txt Entrar neste site/arquivo e estudar esse aplicativo Prof. Ricardo César de Carvalho

http://aurelio.net/vim/vim-basico.txt Entrar neste site/arquivo e estudar esse aplicativo Prof. Ricardo César de Carvalho vi http://aurelio.net/vim/vim-basico.txt Entrar neste site/arquivo e estudar esse aplicativo Administração de Redes de Computadores Resumo de Serviços em Rede Linux Controlador de Domínio Servidor DNS

Leia mais

Tipos de Sistemas Distribuídos (Cluster e Grid)

Tipos de Sistemas Distribuídos (Cluster e Grid) Tipos de Sistemas Distribuídos (Cluster e Grid) Sistemas Distribuídos Mauro Lopes Carvalho Silva Professor EBTT DAI Departamento de Informática Campus Monte Castelo Instituto Federal de Educação Ciência

Leia mais

Introdução. Definição de um Sistema Distribuído (1) Definição de um Sistema Distribuído(2) Metas de Sistemas Distribuídos (2)

Introdução. Definição de um Sistema Distribuído (1) Definição de um Sistema Distribuído(2) Metas de Sistemas Distribuídos (2) Definição de um Sistema Distribuído (1) Introdução Um sistema distribuído é: Uma coleção de computadores independentes que aparecem para o usuário como um único sistema coerente. Definição de um Sistema

Leia mais

SISTEMAS DISTRIBUÍDOS

SISTEMAS DISTRIBUÍDOS SISTEMAS DISTRIBUÍDOS 1. Histórico Primeiros computadores Computadores dos anos 50 e 60 Primeiros computadores com sistemas operacionais Surgimento das redes de computadores Nos anos 70 início das pesquisas

Leia mais

UNIVERSIDADE FEDERAL DE SANTA CATARINA DEPARTAMENTO DE INFORMÁTICA E ESTÁTISTICA GRADUAÇÃO EM CIÊNCIAS DA COMPUTAÇÃO DISCIPLINA: COMUNICAÇÃO DE DADOS

UNIVERSIDADE FEDERAL DE SANTA CATARINA DEPARTAMENTO DE INFORMÁTICA E ESTÁTISTICA GRADUAÇÃO EM CIÊNCIAS DA COMPUTAÇÃO DISCIPLINA: COMUNICAÇÃO DE DADOS UNIVERSIDADE FEDERAL DE SANTA CATARINA DEPARTAMENTO DE INFORMÁTICA E ESTÁTISTICA GRADUAÇÃO EM CIÊNCIAS DA COMPUTAÇÃO DISCIPLINA: COMUNICAÇÃO DE DADOS PROFESSOR: CARLOS BECKER WESTPHALL Terceiro Trabalho

Leia mais

Na medida em que se cria um produto, o sistema de software, que será usado e mantido, nos aproximamos da engenharia.

Na medida em que se cria um produto, o sistema de software, que será usado e mantido, nos aproximamos da engenharia. 1 Introdução aos Sistemas de Informação 2002 Aula 4 - Desenvolvimento de software e seus paradigmas Paradigmas de Desenvolvimento de Software Pode-se considerar 3 tipos de paradigmas que norteiam a atividade

Leia mais

Sistemas Operacionais. Prof. André Y. Kusumoto andrekusumoto.unip@gmail.com

Sistemas Operacionais. Prof. André Y. Kusumoto andrekusumoto.unip@gmail.com Sistemas Operacionais Prof. André Y. Kusumoto andrekusumoto.unip@gmail.com Introdução Um sistema operacional é um programa que atua como intermediário entre o usuário e o hardware de um computador. O propósito

Leia mais

Fundamentos de Sistemas Computacionais Introdução

Fundamentos de Sistemas Computacionais Introdução Fundamentos de Sistemas Computacionais Introdução Prof. Eduardo Alchieri Sistema Computacional Hardware Software Usuários Um ou mais processadores, memória, discos, impressoras, teclado, mouse, monitor,

Leia mais

Hardware (Nível 0) Organização. Interface de Máquina (IM) Interface Interna de Microprogramação (IIMP)

Hardware (Nível 0) Organização. Interface de Máquina (IM) Interface Interna de Microprogramação (IIMP) Hardware (Nível 0) Organização O AS/400 isola os usuários das características do hardware através de uma arquitetura de camadas. Vários modelos da família AS/400 de computadores de médio porte estão disponíveis,

Leia mais

Sistemas Operacionais

Sistemas Operacionais Sistemas Operacionais Sistemas Operacionais Prof. Marcelo Sabaris Carballo Pinto Gerenciamento de Dispositivos Gerenciamento de Dispositivos de E/S Introdução Gerenciador de Dispositivos Todos os dispositivos

Leia mais

Notas da Aula 17 - Fundamentos de Sistemas Operacionais

Notas da Aula 17 - Fundamentos de Sistemas Operacionais Notas da Aula 17 - Fundamentos de Sistemas Operacionais 1. Gerenciamento de Memória: Introdução O gerenciamento de memória é provavelmente a tarefa mais complexa de um sistema operacional multiprogramado.

Leia mais

Sistemas Distribuídos

Sistemas Distribuídos Sistemas Distribuídos Modelo Cliente-Servidor: comunicação orientada por mensagem e comunicação orientada por fluxo Prof. MSc. Hugo Souza Continuando o módulo 03 da primeira unidade, iremos abordar sobre

Leia mais

Banco de Dados I. Apresentação (mini-currículo) Conceitos. Disciplina Banco de Dados. Cont... Cont... Edson Thizon (edson@esucri.com.

Banco de Dados I. Apresentação (mini-currículo) Conceitos. Disciplina Banco de Dados. Cont... Cont... Edson Thizon (edson@esucri.com. Sistemas da Informação Banco de Dados I Edson Thizon (edson@esucri.com.br) 2008 Apresentação (mini-currículo) Formação Acadêmica Mestrando em Ciência da Computação (UFSC/ ) Créditos Concluídos. Bacharel

Leia mais

UNIVERSIDADE. Sistemas Distribuídos

UNIVERSIDADE. Sistemas Distribuídos UNIVERSIDADE Sistemas Distribuídos Ciência da Computação Prof. Jesus José de Oliveira Neto Comunicação Inter-Processos Sockets e Portas Introdução Sistemas distribuídos consistem da comunicação entre processos

Leia mais

Sistema de Computação

Sistema de Computação Sistema de Computação Máquinas multinível Nível 0 verdadeiro hardware da máquina, executando os programas em linguagem de máquina de nível 1 (portas lógicas); Nível 1 Composto por registrados e pela ALU

Leia mais

SISTEMAS OPERACIONAIS ABERTOS Prof. Ricardo Rodrigues Barcelar http://www.ricardobarcelar.com

SISTEMAS OPERACIONAIS ABERTOS Prof. Ricardo Rodrigues Barcelar http://www.ricardobarcelar.com - Aula 2-1. PRINCÍPIOS DE SOFTWARE DE ENTRADA E SAÍDA (E/S) As metas gerais do software de entrada e saída é organizar o software como uma série de camadas, com as mais baixas preocupadas em esconder as

Leia mais

Relatorio do trabalho pratico 2

Relatorio do trabalho pratico 2 UNIVERSIDADE FEDERAL DE SANTA CATARINA INE5414 REDES I Aluno: Ramon Dutra Miranda Matricula: 07232120 Relatorio do trabalho pratico 2 O protocolo SNMP (do inglês Simple Network Management Protocol - Protocolo

Leia mais

Sistemas distribuídos:comunicação

Sistemas distribuídos:comunicação M. G. Santos marcela@estacio.edu.br Faculdade Câmara Cascudo - Estácio de Sá 16 de abril de 2010 Formas de comunicação Produtor-consumidor: comunicação uni-direccional, com o produtor entregando ao consumidor.

Leia mais

Protocolos de Redes Revisão para AV I

Protocolos de Redes Revisão para AV I Protocolos de Redes Revisão para AV I 01 Aula Fundamentos de Protocolos Conceituar protocolo de rede; Objetivos Compreender a necessidade de um protocolo de rede em uma arquitetura de transmissão entre

Leia mais

Bancos de dados distribuídos Prof. Tiago Eugenio de Melo tiagodemelo@gmail.com. http://www.tiagodemelo.info

Bancos de dados distribuídos Prof. Tiago Eugenio de Melo tiagodemelo@gmail.com. http://www.tiagodemelo.info Bancos de dados distribuídos Prof. Tiago Eugenio de Melo tiagodemelo@gmail.com Última atualização: 20.03.2013 Conceitos Banco de dados distribuídos pode ser entendido como uma coleção de múltiplos bds

Leia mais

Prof. Samuel Henrique Bucke Brito

Prof. Samuel Henrique Bucke Brito - QoS e Engenharia de Tráfego www.labcisco.com.br ::: shbbrito@labcisco.com.br Prof. Samuel Henrique Bucke Brito Introdução Em oposição ao paradigma best-effort (melhor esforço) da Internet, está crescendo

Leia mais

Figura 01 Kernel de um Sistema Operacional

Figura 01 Kernel de um Sistema Operacional 01 INTRODUÇÃO 1.5 ESTRUTURA DOS SISTEMAS OPERACIONAIS O Sistema Operacional é formado por um Conjunto de rotinas (denominado de núcleo do sistema ou kernel) que oferece serviços aos usuários e suas aplicações

Leia mais

DIMENSIONANDO PROJETOS DE WEB-ENABLING. Uma aplicação da Análise de Pontos de Função. Dimensionando projetos de Web- Enabling

DIMENSIONANDO PROJETOS DE WEB-ENABLING. Uma aplicação da Análise de Pontos de Função. Dimensionando projetos de Web- Enabling DIMENSIONANDO PROJETOS DE WEB-ENABLING Uma aplicação da Análise de Pontos de Função Dimensionando projetos de Web- Enabling Índice INTRODUÇÃO...3 FRONTEIRA DA APLICAÇÃO E TIPO DE CONTAGEM...3 ESCOPO DA

Leia mais

O que veremos nesta aula? Principais Aspectos de Sistemas Operacionais. Visão geral de um sistema computacional

O que veremos nesta aula? Principais Aspectos de Sistemas Operacionais. Visão geral de um sistema computacional O que veremos nesta aula? Principais Aspectos de Sistemas Operacionais Laboratório de Sistemas Operacionais Aula 1 Flávia Maristela (flavia@flaviamaristela.com) Tudo o que já vimos antes... Introdução

Leia mais

SISTEMAS OPERACIONAIS

SISTEMAS OPERACIONAIS SISTEMAS OPERACIONAIS Tópico 4 Estrutura do Sistema Operacional Prof. Rafael Gross prof.rafaelgross@fatec.sp.gov.br FUNÇÕES DO NUCLEO As principais funções do núcleo encontradas na maioria dos sistemas

Leia mais

PROCESSO DE DESENVOLVIMENTO DE SOFTWARE. Modelos de Processo de Desenvolvimento de Software

PROCESSO DE DESENVOLVIMENTO DE SOFTWARE. Modelos de Processo de Desenvolvimento de Software PROCESSO DE DESENVOLVIMENTO DE SOFTWARE Introdução Modelos de Processo de Desenvolvimento de Software Os modelos de processos de desenvolvimento de software surgiram pela necessidade de dar resposta às

Leia mais

Sistemas Computacionais II Professor Frederico Sauer

Sistemas Computacionais II Professor Frederico Sauer Sistemas Computacionais II Professor Frederico Sauer Livro-texto: Introdução à Organização de Computadores 4ª edição Mário A. Monteiro Livros Técnicos e Científicos Editora. Atenção: Este material não

Leia mais

Informática I. Aula 22. http://www.ic.uff.br/~bianca/informatica1/ Aula 22-03/07/06 1

Informática I. Aula 22. http://www.ic.uff.br/~bianca/informatica1/ Aula 22-03/07/06 1 Informática I Aula 22 http://www.ic.uff.br/~bianca/informatica1/ Aula 22-03/07/06 1 Critério de Correção do Trabalho 1 Organização: 2,0 O trabalho está bem organizado e tem uma coerência lógica. Termos

Leia mais

MÓDULO 8 ARQUITETURA DOS SISTEMAS DE BANCO DE DADOS

MÓDULO 8 ARQUITETURA DOS SISTEMAS DE BANCO DE DADOS MÓDULO 8 ARQUITETURA DOS SISTEMAS DE BANCO DE DADOS Quando falamos em arquitetura, normalmente utilizamos esse termo para referenciar a forma como os aplicativos computacionais são estruturados e os hardwares

Leia mais

IP significa Internet Protocol. A Internet é uma rede, e assim como ocorre em qualquer tipo de rede, os seus nós (computadores, impressoras, etc.

IP significa Internet Protocol. A Internet é uma rede, e assim como ocorre em qualquer tipo de rede, os seus nós (computadores, impressoras, etc. Endereços IP Endereços IP IP significa Internet Protocol. A Internet é uma rede, e assim como ocorre em qualquer tipo de rede, os seus nós (computadores, impressoras, etc.) precisam ter endereços. Graças

Leia mais

Protocolo. O que é um protocolo? Humano: que horas são? eu tenho uma pergunta

Protocolo. O que é um protocolo? Humano: que horas são? eu tenho uma pergunta Protocolo O que é um protocolo? Humano: que horas são? eu tenho uma pergunta Máquina: Definem os formatos, a ordem das mensagens enviadas e recebidas pelas entidades de rede e as ações a serem tomadas

Leia mais

Rede d s d e d Com o pu p t u ado d r o es Conceitos Básicos M d o e d los o de d Re R de d s:

Rede d s d e d Com o pu p t u ado d r o es Conceitos Básicos M d o e d los o de d Re R de d s: Tecnologia em Redes de Computadores Redes de Computadores Professor: André Sobral e-mail: alsobral@gmail.com Conceitos Básicos Modelos de Redes: O O conceito de camada é utilizado para descrever como ocorre

Leia mais

Universidade Federal de Santa Maria Curso de Arquivologia. Disciplina de Banco de Dados Aplicados à Arquivística. Versao 1.

Universidade Federal de Santa Maria Curso de Arquivologia. Disciplina de Banco de Dados Aplicados à Arquivística. Versao 1. Universidade Federal de Santa Maria Curso de Arquivologia Disciplina de Banco de Dados Aplicados à Arquivística Prof. Andre Zanki Cordenonsi Versao 1.0 Março de 2008 Tópicos Abordados Conceitos sobre Banco

Leia mais

PARANÁ GOVERNO DO ESTADO

PARANÁ GOVERNO DO ESTADO A COMUNICAÇÃO NA INTERNET PROTOCOLO TCP/IP Para tentar facilitar o entendimento de como se dá a comunicação na Internet, vamos começar contando uma história para fazer uma analogia. Era uma vez, um estrangeiro

Leia mais

Máquinas Multiníveis

Máquinas Multiníveis Infra-Estrutura de Hardware Máquinas Multiníveis Prof. Edilberto Silva www.edilms.eti.br edilms@yahoo.com Sumário Conceitos básicos Classificação de arquiteturas Tendências da tecnologia Família Pentium

Leia mais

Modelos de Camadas. Professor Leonardo Larback

Modelos de Camadas. Professor Leonardo Larback Modelos de Camadas Professor Leonardo Larback Modelo OSI Quando surgiram, as redes de computadores eram, em sua totalidade, proprietárias, isto é, uma determinada tecnologia era suportada apenas por seu

Leia mais

Como foi exposto anteriormente, os processos podem ter mais de um fluxo de execução. Cada fluxo de execução é chamado de thread.

Como foi exposto anteriormente, os processos podem ter mais de um fluxo de execução. Cada fluxo de execução é chamado de thread. 5 THREADS Como foi exposto anteriormente, os processos podem ter mais de um fluxo de execução. Cada fluxo de execução é chamado de thread. 5.1 VISÃO GERAL Uma definição mais abrangente para threads é considerá-lo

Leia mais

ADDRESS RESOLUTION PROTOCOL. Thiago de Almeida Correia

ADDRESS RESOLUTION PROTOCOL. Thiago de Almeida Correia ADDRESS RESOLUTION PROTOCOL Thiago de Almeida Correia São Paulo 2011 1. Visão Geral Em uma rede de computadores local, os hosts se enxergam através de dois endereços, sendo um deles o endereço Internet

Leia mais

Introdução à Computação

Introdução à Computação Aspectos Importantes - Desenvolvimento de Software Motivação A economia de todos países dependem do uso de software. Cada vez mais, o controle dos processos tem sido feito por software. Atualmente, os

Leia mais

GARANTIA DA QUALIDADE DE SOFTWARE

GARANTIA DA QUALIDADE DE SOFTWARE GARANTIA DA QUALIDADE DE SOFTWARE Fonte: http://www.testexpert.com.br/?q=node/669 1 GARANTIA DA QUALIDADE DE SOFTWARE Segundo a NBR ISO 9000:2005, qualidade é o grau no qual um conjunto de características

Leia mais