FAED Trabalho de Conclusão de Curso ESTUDO SOBRE DIFERENTES TÉCNICAS DE GERENCIAMENTO DE MEMÓRIA Marcos Talau Curso de Bacharelado em Sistemas de Informação Dois Vizinhos, PR, Brasil 2005 FAED Trabalho de Conclusão de Curso ESTUDO SOBRE DIFERENTES TÉCNICAS DE GERENCIAMENTO DE MEMÓRIA Marcos Talau Curso de Bacharelado em Sistemas de Informação Dois Vizinhos, PR, Brasil 2005 ii ESTUDO SOBRE DIFERENTES TÉCNICAS DE GERENCIAMENTO DE MEMÓRIA Marcos Talau Trabalho de Conclusão de Curso apresentado ao Curso de Bacharelado em Sistemas de Informação da Faculdade Educacional de Dois Vizinhos – UNISEP (FAED/UNISEP, PR), como requisito parcial para a obtenção do grau de Bacharel em Sistemas de Informação Curso de Sistemas de Informação Dois Vizinhos, PR, Brasil 2005 iii União de Ensino do Sudoeste do Paraná Faculdade Educacional de Dois Vizinhos Curso de Bacharelado em Sistemas de Informação A Comissão Examinadora, assinada abaixo, aprova o Trabalho de Conclusão de Curso ESTUDO SOBRE DIFERENTES TÉCNICAS DE GERENCIAMENTO DE MEMÓRIA elaborada por Marcos Talau como requisito parcial para obtenção do grau de Bacharel em Sistemas de Informação COMISSÃO EXAMINADORA _______________________________________ Giovani Motter (Orientador) _______________________________________ Fabio Alexandre Taffe (Professor) _______________________________________ Edivane Bellé (Professora) Dois Vizinhos, 07 de Dezembro de 2005 iv Este trabalho é dedicado a minha Mãe, Tia e avó. v AGRADECIMENTOS Agradeço ao meu orientador Giovani Motter pelo apoio e dedicação com meus estudos. Meus agradecimentos também ao meu amigo Felipe Augusto van de Wiel pelo fornecimento de informações a respeito do gerenciamento de memória e o processo de desenvolvimento do Linux. vi LISTA DE FIGURAS Figura 1: ENIAC (ETSI2, 2005).................................................................................................4 Figura 2: IBM PC AT (CHELLO, 2005).......................................................................................7 Figura 3: Arquitetura de um sistema operacional (SILBERSCHATZ et al., 2002)...................10 Figura 4: Sistema batch (TANENBAUM, 2003).......................................................................11 Figura 5: Overlay para um montador de dois passos (SILBERSCHATZ et al., 2000)..............23 Figura 6: A relação entre endereços virtuais e endereços físicos de memória (TANENBAUM e WOODHULL, 2000)................................................................................................................25 Figura 7: (a) Um endereço de 32 bits com dois campos de tabela de páginas. (b) Tabelas de páginas de dois níveis (TANENBAUM e WOODHULL, 2000)...................................................28 Figura 8: Tabela de página invertida (SILBERSCHATZ et al., 2000).......................................31 Figura 9: Swapping em memória virtual (MACHADO e MAIA, 2002).....................................33 Figura 10: Uma memória segmentada permite que cada tabela cresça ou escolha independentemente das outras tabelas (TANENBAUM e WOODHULL, 2000).......................34 Figura 11: Visão de usuário de um programa (SILBERSCHATZ et al., 2000).........................35 Figura 12: Thrashing (SILBERSCHATZ et al., 2000)...............................................................37 Figura 13: Tela de opções do simulador TSM........................................................................54 Figura 14: Simulador TSM sendo executado com o algoritmo LRU.......................................54 Figura 15: Gráfico com algoritmos de alocação....................................................................57 Figura 16: Gráfico com algoritmos de páginas com 50 páginas...........................................59 Figura 17: Gráfico com algoritmos de páginas com 100 páginas.........................................59 Figura 18: Gráfico com algoritmos de páginas com 200 páginas.........................................60 Figura 19: Gráfico com algoritmos de páginas com 1000 páginas.......................................61 Figura 20: Gráfico com algoritmos de páginas com 2000 páginas.......................................61 Figura 21: Gráfico do algoritmo ARC (MEGIDDO e MODHA, 03/2003)...................................62 Figura 22: Gráfico do algoritmo CAR (BANSAL e MODHA).....................................................63 Figura 23: Gráfico do algoritmo CLOCK-PRO (JIANG et al.)....................................................64 Figura 24: Arquitetura de um kernel.....................................................................................66 vi LISTA DE ABREVIATURAS E SIGLAS ENIAC DEC FMS LSI DOS SO MIT SMP UCP PDA CE LFU PFF LIRS ARC JOB TSM OPT TLB Electronic Numerial Integrator and Computer Digital Equipament Corporation Fortran Monitor System Large Scale Integration Disk Operating System Sistema Operacional Massachisetts Institute of Technology Symmetric Multriprocessing Unidade Central de Processamento Personal Digital Assistant Consumer Eletronics Least Frequently Used Freqüência de Falta de Páginas Low Inter-reference Recency Set Adaptative Replacement Cache Trabalho Talau Simulador de Memória Ótimo Translation Lookaside Buffers vii SUMÁRIO 1 INTRODUÇÃO.......................................................................................................................1 1.1 Objetivos____________________________________________________________________________2 1.1.1 Objetivo Geral..........................................................................................................2 1.1.2 Objetivo Específico..................................................................................................2 2 CONHECENDO A ÁREA.........................................................................................................3 2.1 Histórico das Gerações de Computadores____________________________________________3 2.1.1 1ª Geração...............................................................................................................3 2.1.2 2ª Geração...............................................................................................................4 2.1.3 3ª Geração...............................................................................................................5 2.1.4 4ª Geração...............................................................................................................6 2.2 SISTEMAS OPERACIONAIS____________________________________________________________8 2.2.1 O que é um sistema operacional?...........................................................................8 2.2.2 Tipos de sistemas operacionais.............................................................................10 3 GERENCIAMENTO DE MEMÓRIA.........................................................................................16 3.1 Introdução__________________________________________________________________________16 3.2 Monoprogramação__________________________________________________________________17 3.3 Multiprogramação__________________________________________________________________17 3.3.1 Partições de memória............................................................................................17 3.3.2 Swapping...............................................................................................................21 3.3.3 Memória virtual.....................................................................................................22 4 ALGORITMOS......................................................................................................................38 4.1 Alocação memória__________________________________________________________________38 4.1.1 Conceito................................................................................................................38 4.1.2 First-fit...................................................................................................................38 4.1.3 Best-fit...................................................................................................................39 4.1.4 Worst-fit.................................................................................................................39 4.1.5 Next-fit...................................................................................................................40 4.1.6 Quick-fit.................................................................................................................40 4.2 Algoritmos de substituição de páginas______________________________________________41 4.2.1 LRU........................................................................................................................41 4.2.2 LFU........................................................................................................................42 4.2.3 NUR.......................................................................................................................42 4.2.4 NFU........................................................................................................................43 4.2.5 MRU.......................................................................................................................43 4.2.6 Ótimo.....................................................................................................................44 viii 4.2.7 FIFO.......................................................................................................................45 4.2.8 SC..........................................................................................................................45 4.2.9 CLOCK....................................................................................................................46 4.2.10 WSCLOCK.............................................................................................................46 4.2.11 PFF.......................................................................................................................46 4.2.12 LIRS.....................................................................................................................47 4.2.13 ARC......................................................................................................................48 4.2.14 Clock-Pro..............................................................................................................49 4.2.15 CAR......................................................................................................................50 4.2.16 CART....................................................................................................................50 5 COMPARAÇÃO DOS ALGORITMOS......................................................................................52 5.1 Gráficos____________________________________________________________________________56 5.1.1 Simulador FITS.......................................................................................................56 5.1.2 Simulador TSM.......................................................................................................58 5.1.3 Outras pesquisas...................................................................................................62 6 CONCLUSÃO.......................................................................................................................65 6.1 Trabalhos Futuros___________________________________________________________________66 ix RESUMO Na história da computação mudanças ocorrem com vasta freqüência, surgem novas tecnologias e novos dispositivos tudo isso para aplicar mais funcionalidade a esta grande máquina. Todo computador ou sistema baseado nele, possui um componente vital para seu funcionamento este é a memória. Como grande parte dos projetos de computadores foram feitos com base na arquitetura de John Von Neumann, toda instrução para ser executada antes deve estar presente na memória. Com esta importância e comprometimento aplicado a ela, devem existir necanismos de hardware e software para facilitar este trabalho. A técnica de gerencia de memória a ser escolhida para o sistema operacional deve ter parte dela ligada ao projeto do hardware, para deixar este processo incessante mais rápido. A camada de software da gerencia de memória atua no controle da camada de hardware da memória. Este trabalho buscará uma revisão bibliográfica e comparação dos algoritmos de gerenciamento de memória, bem como o desenvolvimento de um aplicativo simulador destes algoritmos. Palavras-chave: Gerenciamento de memória, Sistema Operacional, Algoritmos. x 1 INTRODUÇÃO Computadores são formados por circuitos eletrônicos denominados hardware e por um conjunto de instruções inseridas em um nível de abstração pelo usuário denominada software. O principal software de qualquer computador é o sistema operacional. De acordo com Tanenbaum (2003) o sistema operacional tem o objetivo primordial de esconder a complexidade por traz do hardware do usuário do sistema. O sistema operacional possui uma camada que esconde o hardware do usuário, deixando ao usuário uma sensação de controle do computador. Este software que trabalha com a máquina executando sempre em modo supervisor, ou seja, o único com acesso completo aos recursos do computador. Uma das partes do sistema operacional que é mais utilizada é o sistema de memória. Todos os drivers, programas e dispositivos tem que manter um contato com a memória para poder funcionar adequadamente. De acordo com Murdocca e Heuring (2000), a memória de um computador é um conjunto de registradores com uma seqüência numérica. A organização destes endereços é realizada de uma forma linear numerada, o número que identifica um local de memória tem o nome de endereço. Uma memória é dividida em diferentes partes pelo sistema operacional para o controle e trabalho. Devido a alta taxa de uso da memória e sua importância, é necessário ter mecanismos extremamente rápidos para realizar suas tarefas, pois, se um esquema de gerenciamento de memória for lento ou problemático todo o sistema entra em declínio. 2 1.1 Objetivos 1.1.1 Objetivo Geral O objetivo deste trabalho é realizar um levantamento bibliográfico do gerenciamento de memória, realizar um estudo dos algoritmos de alocação e substituição de páginas e por final desenvolver um simulador de memória. 1.1.2 Objetivo Específico • Documentar a evolução dos sistemas operacionais e tipos de sistemas operacionais. • Realizar estudo sobre gerenciamento de memória. • Descrever os algoritmos de alocação de memória e substituição de páginas de memória. • Desenvolver um software simulador de algoritmos de memória, contendo um sistema virtual de memória para ser uma base aos algoritmos de substituição de páginas. Este trabalho terá como contribuição um estudo de sistemas de memória e resultados através de gráficos sobre os algoritmos de alocação e substituição de páginas de memória, tento como fator de análise o problema da falta de páginas. 3 2 CONHECENDO A ÁREA 2.1 Histórico das Gerações de Computadores 2.1.1 1ª Geração “O ENIAC (Computador e Integrador Numérico Eletrônico – Electronic Numerial Integrator and Computer), projetado e construído sob a supervisão de John Mauchly e John Presper Eckert na Universidade da Pensilvânia, foi o primeiro computador eletrônico digital de propósito geral em todo o mundo.” (STALLINGS, 2002, p. 19). Segundo Stallings (2002) o ENIAC foi desenvolvido para fazer cálculos balísticos para ser utilizado na segunda guerra mundial. Estes cálculos eram feitos manualmente por um grande número de pessoas, isso demorava muito tempo chegando até a dias, pois as equações eram muito complexas. Mauchly e Eckert, um professor de engenharia elétrica da Universidade da Pensilvânia e um aluno seu de pós-graduação tiveram a idéia de construção desta máquina, eles conversaram com o exercito americano que apoiou a proposta. Quando o ENIAC foi terminado ele pesava 30 toneladas, ocupava um espaço de 140 metros quadrados e tinha 18 mil válvulas. Este computador usava uma base decimal e possuía uma memória de 20 acumuladores cada um com uma capacidade e armazenamento de um número decimal de dez dígitos decimais. Um grande problema do ENIAC era que ele tinha de ser programado totalmente de forma manual ligando e desligando cabos e chaves. Em 1946 quando este computador foi concluído já era muito tarde para ser usado na segunda guerra mundial, mas o ENIAC serviu para ajudar a verificar a viabilidade da bomba H. Em 1955 o ENIAC foi desativado. (STALLINGS, 2002) 4 Naquela época, um mesmo grupo de pessoas, construía, programava, operava e realizava a manutenção de cada máquina. Toda a programação era feita em código absoluto e muitas vezes conectando plugs em painéis para controlar as funções básicas na maquina. Não havia linguagens de programação (nem mesmo a linguagem de montagem existia). Os sistemas operacionais também ainda não haviam sido inventados. O modo normal de operação era o seguinte: o programador reservava antecipadamente tempo de máquina em uma planilha, ia para a sala da máquina, inseria seu painel de programação no computador e passava algumas horas torcendo para que nenhuma das válvulas queimasse durante a execução. Praticamente todos os problemas eram cálculos numéricos diretos, como determinar tabelas de senos, co-senos e logaritmos. No início da década de 50, esse processo havia se aprimorado com a introdução de perfuradoras de cartões. Erra possível, então, escrever programas em cartões e lê-los em lugar de painéis de programação; de outra maneira o procedimento seria o mesmo. (TANENBAUM, 2003, p. 05) Figura 1: ENIAC (ETSI2, 2005) 2.1.2 2ª Geração A primeira grande mudança nos computadores eletrônicos veio com a substituição da válvula pelo transistor. O transistor é menor, mais barato e dissipa menos calor do que a válvula e, assim como uma válvula, também pode ser utilizado para a construção de computadores. Ao contrário da válvula, que requer uso de fios, placas de metal, cápsula de vidro e vácuo, o transistor é um dispositivo de estado sólido, feito de silício. O transistor foi inventado na Bell Laboratories, em 1947, e iniciou uma revolução na indústria eletrônica nos anos 50. Entretanto, apenas no final da década de 50, computadores totalmente transistorizados tornaram-se comercialmente disponíveis. (STALLINGS, 2002, p. 27) Conforme Stallings (2002) os computadores tinham as unidades lógica, aritmética e unidade de controle mais complexa. Os computadores também possuíam linguagens de programação de alto nível e incluíam software de 5 sistema. Nesta geração também surgiu a DEC, que lançou o PDP-1, que deu inicio a era dos microcomputadores. De acordo com Tanenbaum (2003) com o uso do transistor mudou o cenário computacional radicalmente. Os computadores ficaram mais confiáveis ao ponto de se funcionar por um longo tempo sem apresentar anomalias e problemas. Nesta geração ocorreu uma separação exata entre projetistas, fabricantes, programadores e técnicos de manutenção. “Os grandes computadores de segunda geração foram usados, em sua maioria, para cálculos científicos, como equações diferenciais parciais, muito freqüentes na física e na engenharia. Eles eram preponderantemente programados em FORTRAN e em linguagem de montagem. Os sistemas operacionais típicos eram o FMS e o IBSYS, sistemas operacionais da IBO para o 7094.” (TANENBAUM, 2003, p. 06) 2.1.3 3ª Geração De acordo com Stallings (2002) na década de 50 e o início dos anos 60 os equipamentos eletrônicos tinham basicamente os seguintes componentes discretos: transistores, resistores e capacitores. Estes objetos eram fabricados separadamente e eram ligados através de cabos e também com o uso de placas de circuito impresso. Tinha-se muita dificuldade para lidar com transistores neste esquema, pois os computadores tinham milhares de transistores. “Em 1958, foi desenvolvida uma nova técnica que revolucionou os equipamentos eletrônicos e iniciou a era da microeletrônica: a invenção do circuito integrado. Esse circuito caracteriza computadores.” (STALLINGS, 2002, p. 29) a terceira geração de 6 2.1.4 4ª Geração Conforme Tanenbaum (2003) com a criação de circuitos integrados em larga escala LSI nasceu à era dos computadores pessoais. Falando de arquitetura os microcomputadores não de diferenciavam muito da classe PDP-11, porém o preço era o grande diferencial, e com isso ouve uma enorme venda de microcomputadores pessoais. Em 1974 a Intel lança o 8080, um processador de 8 bits, porém faltava um sistema operacional para ele. A Intel pediu a Gary Kildall escreve-lo, Kildall tinha um sistema operacional baseado em disco denominado CP/M. O CP/M não foi de muito agrado a Intel, Kildall então decidiu abri uma empresa a Digital Research para trabalhar no CP/M. (TANENBAUM, 2003) No início da década de 80 a IBM criou o IBM PC. A IBM precisava de um sistema operacional para o seu computador, tentou entrar em contato com a Digital Research que dominava o mundo dos sistemas operacionais na época. A IBM entrou em contato com Kildall, ele tomou a pior decisão da história dos negócios, recusou trabalhar com a IBM. Ainda assim a IBM necessitava de um sistema operacional para seu computador, quando entrou em contato novamente com Bill Gates, ele comprou o sistema operacional DOS da empresa Seattle Computer Products e o forneceu a IBM. Tempos depois a Microsoft contratou o criador do DOS Tim Paterson para trabalha para ela. Assim nasceu a maior fortuna do mundo. (TANENBAUM, 2003) 7 Figura 2: IBM PC AT (CHELLO, 2005) 8 2.2 SISTEMAS OPERACIONAIS 2.2.1 O que é um sistema operacional? O sistema operacional (SO) é o software que controla a execução de programas memória, só podem ser executadas de modo rápido e eficiente se o SO dispor de um suporte adequado do hardware do processador. Quase todos os processadores dispõem desse suporte, em maior ou menor extensão, incluindo hardware de gerenciamento de memória virtual e de gerenciamento de processos. Isso inclui registradores de propósito especial e áreas de armazenamento temporário, além de um conjunto de circuitos para realizar tarefas básica de gerenciamento de recursos. (STALLINGS, 2002, p. 240) De acordo com Tanenbaum e Woodhull (2000), os sistemas operacionais executam basicamente duas funções: 1ª O sistema operacional está encarregado de fazer toda a comunicação com o hardware, criando assim abstrações facilitar a vida do programador. "...O programa que esconde do programador a verdade sobre o hardware e apresenta uma bela e simples visão de nomes de arquivos que podem ser lidos e gravados é, naturalmente o sistema operacional..." (TANENBAUM e WOODHULL, 2000, p. 19) 2ª O sistema operacional dispõe de um hardware para realizar operações,o SO deve gerenciar os recursos que possui de uma forma ordenada e estável. ...Os computadores modernos consistem em processadores, memórias, temporizadores, discos, mouses, interfaces de rede, impressoras a laser e uma ampla variedade de outros dispositivos. Na visão alternativa, o trabalho do sistema operacional é oferecer uma alocação ordenada e controlada dos processadores, das memórias e dos dispositivos de E/S entre os vários programas que competem por eles.(TANENBAUM e WOODHULL, 2000, p. 19) Um sistema operacional moderno consiste em um ou mais processadores, memória principal, discos, impressoras, teclado, monitor, interfaces de 9 rede e outros dispositivos de entrada e saída. Enfim, é um sistema complexo. Desenvolver programas que mantenham o controle de todos esses componentes e os utilizem corretamente de maneira otimizada é um trabalho extremamente difícil. Por isso, os computadores têm um dispositivo denominado sistema operacional, cujo trabalho é gerenciar esses componentes e fornecer aos programas do usuário uma interface com o hardware mais simples. (TANENBAUM, 2003, p. 1) "Um sistema operacional, por mais complexo que possa parecer, é apenas um conjunto de rotinas executado pelo processador, de forma semelhante aos programas dos usuários. Sua principal função é controlar o funcionamento dos seus diversos recursos, como processadores, memórias e dispositivos de entrada e saída." (MACHADO e MAIA, 2002) Um sistema operacional é um programa que atua como intermediário entre o usuário e o hardware de um computador. O propósito de um sistema operacional é fornecer um ambiente no qual o usuário possa executar programas. O principal objetivo de um sistema operacional é portanto o uso do sistema de computação conveniente. Uma meta secundária é usar o hardware do computador de forma eficiente. (SILBERSCHATZ et al., 2000, p. 3) 10 Figura 3: Arquitetura de um sistema operacional (SILBERSCHATZ et al., 2002) 2.2.2 Tipos de sistemas operacionais 2.2.2.1Sistemas em lote Segundo Silberschatz et al. (2000) os primeiros computadores tinham como dispositivo de entrada leitoras de cartões e unidades de fita. O usuário não podia interagir diretamente com este sistema. Para trabalhar nestas máquinas era necessário introduzir os dados através de um cartão perfurado. Os sistemas operacionais destes computadores ficavam sempre residentes na memória, eles processam o JOB e mudava o controle para o próximo JOB. Com o surgimento de discos o sistema operacional conseguia armazenar os JOBS no disco, com isso, o SO realizava um escalonamento de JOBS para realizar o processamento de JOBS mais rapidamente, pois poderia utilizar os recursos de forma mais eficaz. escalonamento de JOBS a multiprogramação flui. Com a utilização do 11 "Em sistemas batch, quando bem projetados, podem ser bastante eficientes, devido à melhor utilização do processador; entretanto, podem oferecer tempo de resposta longos. Atualmente, os sistemas operacionais implementam ou simulam o processamento batch, não existindo sistemas exclusivamente dedicados a este tipo de processamento." (MACHADO e MAIA, 2002, p. 17) Figura 4: Sistema batch (TANENBAUM, 2003) 2.2.2.2Sistemas de tempo compartilhado Segundo Silberschatz et al. (2000) em sistemas de tempo compartilhado a CPU executa mais de um JOB, alterando o tempo de execução entre eles. Nestes sistemas o usuário passa um comando e tem uma resposta quase que imediata do sistema. Com um sistema de tempo compartilhado vários usuários podem usar um computador ao mesmo tempo, cada ação do usuário tende a ser curta assim um pequeno tempo de CPU é o bastante para cada usuário. Estes sistemas são mais complexos que sistemas operacionais multiprogramados. "...A idéia do tempo compartilhado foi demonstrada já em 1960, mas como os sistemas de tempo compartilhado são difíceis e caros de construir, só se tornaram comuns no início dos anos 70. Embora algum processamento batch ainda ocorra, a maioria dos sistemas hoje é de tempo compartilhado..." (SILBERSCHATZ et al., 2000, p. 7) 12 Os sistemas de tempo compartilhado (time-sharing) permitem que diversos programas sejam executados a partir da divisão do tempo do processador em pequenos intervalos, denominados fatia de tempo (timeslice). Caso a fatia de tempo não seja suficiente para a conclusão do programa, esse é interrompido pelo sistema operacional e substituído por um outro, enquanto fica aguardando por uma nova fatia de tempo. O sistema cria um ambiente de trabalho próprio, dando a impressão de que todo o sistema está dedicado, exclusivamente, para cada usuário. (MACHADO e MAIA, 2002, p.17) 2.2.2.3Sistemas de computadores pessoais Segundo Silberschatz et al. (2000) os computadores pessoais surgiram nos anos 70, nesta época os sistemas operacionais não eram multiusuário nem multitarefa. Estes sistemas foram evoluindo com o tempo trazendo novos recursos e funcionalidades. Estes sistemas operacionais aproveitaram muito a tecnologia dos sistemas operacionais de mainframes para utilizar nos computadores pessoais. Um bom exemplo desta ação foi o caso do MULTICS: o sistema operacional MULTICS foi criado no MIT e foi usado no mainframe GE 645; Várias soluções que foram criadas para o MULTICS foram adotadas para a criação do UNIX. "Seu trabalho é fornecer uma boa interface para um único usuário. São amplamente usados para processadores de texto, planilhas e acesso à Internet. Exemplos comuns são o Windows 98, o Windows 2000, o sistema operacional Macintosh e o Linux. Sistemas operacionais de computadores pessoais são tão amplamente conhecidos." (TANENBAUM, 2003, p. 14) 2.2.2.4Sistemas paralelos Segundo Silberschatz et al. (2000) sistemas paralelos possuem múltiplos processadores, com o aumento do número de processadores, estimasse que os trabalhos poderão ser realizados em menos tempo. Sistemas multiprocessados tender a trazer economia de dinheiro comparados a vários sistemas de um único processador. Estes são mais tolerantes a falhas do que os sistemas uniprocessador pois se um 13 processador parar o outro pode assumir toda a carga de processamento. Os sistemas com múltiplos processadores são divididos em duas classes: 1ª Multiprocessamento simétrico: Ambos os processadores executam uma cópia idêntica do sistema operacional. No processamento simétrico (SMP) os processos são executados simultaneamente sem ocasionar problemas. Este tipo de sistema deve ser criado com cuidado pois existe um grande compartilhamento de recursos. Os sistemas operacionais: Windows NT, Solaris, Digital UNIX, OS/2 e Linux suportam a tecnologia SMP. 2ª Multiprocessamento assimétrico: Nesta classe cada processador recebe uma tarefa especifica, havendo um processador com a função de mestre que envia instruções para os demais processadores. Um modo cada vez mais comum de obter potência computacional é conectar múltiplas CPUs em um único sistema. Dependendo precisamente de como elas estiverem conectas e o que é compartilhado, esses sistemas são denominados computadores paralelos, multicomputadores ou multiprocessadores. Eles precisam de sistemas operacionais, mas muitos deles são variações dos sistemas operacionais de servidores com aspectos especiais de comunicação e conectividade. (TANENBAUM, 2003, p. 14) Os sistemas com múltiplos processadores caracterizam-se por possuir duas ou mais UCP interligadas e trabalhando em conjunto. A vantagem deste tipo de sistema é permitir que vários programas sejam executados ao mesmo tempo ou que um mesmo programa seja subdividido em partes para serem executadas simultaneamente em mais de um computador. (MACHADO e MAIA, 2002, p. 18) 2.2.2.5Sistema de tempo real Segundo Silberschatz et al. (2000) neste tipo de sistema o tempo é super importante, ele é usado como uma forma de controle em uma aplicação dedicada. Existem sensores que levam os dados até o computador, para ser feita uma análise e provavelmente realizar um ajuste para modificar a entrada dos sensores. Um processamento a ser efetuado deve estritamente ser executado num limite de tempo, caso contrário o 14 sistema não executara totalmente seus objetivos. Existem dois tipos de sistema de tempo real: 1º Sistema de tempo real crítico: Neste sistema deve haver uma garantia que as tarefas sejam executadas a tempo, para realizar este sistema uma série de características de sistemas operacionais devem ser deixadas de lado, pois deve haver uma certeza sobre o tempo. 2º Sistema de tempo real não-crítico: As tarefas são divididas em prioridade até serem totalmente concluídas. Esse sistema está inserido em varias versões do UNIX. Esses sistemas são caracterizados por terem o tempo como um parâmetro fundamental. por exemplo, em sistemas de controle de processos industriais, computadores de tempo real devem coletar dados sobre o processo de produção e usá-los para controlar as máquinas na fábrica. É bastante comum a existência de prazos rígidos para a execução de determinadas tarefas. Por exemplo, se um carro está se movendo por uma linha de montagem, certas ações devem ser realizadas em momentos específicos. Se um robô soldados realiza seu trabalho - soldar muito cedo ou muito tarde, o carro está perdido. (TANENBAUM, 2003, p. 14) "Nos sistemas de tempo real não existe a idéia de fatia de tempo, implementada nos sistemas de tempo compartilhado. Um programa utiliza o processador o tempo que for necessário ou até que apareça outro mais prioritário. Essa importância ou prioridade de execução é definida pela própria aplicação e não pelo sistema operacional, como nos sistemas de tempo compartilhado." (MACHADO e MAIA, 2002, p. 18) 2.2.2.6Sistemas distribuídos Segundo Silberschatz et al. (2000) ocorreram muitas mudanças nos sistemas operacionais com o nascimento da Internet. Os sistemas operacionais começaram a ter navegadores WEB, clientes de e-mail e mecanismos de acesso a redes como os protocolos TCP/IP e PPP. Em 15 sistemas distribuídos os processadores se comunicam a través de linhas de comunicação como linhas de comunicação de operadoras de telefonia. 2.2.2.7Sistemas operacionais de computadores de grande porte "Os sistemas operacionais de computadores de grande porte são sobretudo orientados para o processamento simultâneo de muitos JOBS, sendo que a maioria deles precisa de quantidades prodigiosas de E/S. Estes sistemas operacionais oferecem normalmente três tipos de serviços: em lote (batch), processamento de transações e tempo compartilhado." (TANENBAUM, 2003, p.13) 2.2.2.8Sistemas operacionais embargados Um computador de mão ou PDA (personal digital assistant) é um pequeno computador que cabe em um bolso de camisa e realiza um pequeno número de funções como agenda e livro de endereços. Sistemas embargados são executados em computadores que controlam dispositivos que geralmente não são considerados como computadores, como aparelhos de TB, fornos de microondas e telefones móveis. Eles têm, muitas vezes, características de sistemas de tempo real, mas também apresentam restrições de tamanho, memória e consumo de energia que os fazem especiais. Exemplos desses sistemas operacionais são o PalmOS e o Windows CE (Consumer eletronics). (TANENBAUM, 2003, p. 14) 2.2.2.9Sistemas operacionais de cartões inteligentes Os menores sistemas operacionais são executados em cartões inteligentes dispositivos do tamanho de cartões de crédito que contêm um chip de CPU. Possuem restrições severas de consumo de energia e de memória. Alguns deles podem realizar apenas uma única função, como pagamentos eletrônicos, mas outros podem tratar múltiplas funções no mesmo cartão inteligente. São comumente sistemas operacionais. (TANENBAUM, 2003, p. 14) 16 3 GERENCIAMENTO DE MEMÓRIA 3.1 Introdução A memória é um recurso importante que deve ser gerenciado com cuidado. Enquanto o computador doméstico médio hoje em dia tem 50 vezes mais memória do que o IBM 7024, o maior computador do mundo no início da década de 60, os programas estação crescendo tão rapidamente quanto às memórias. Parafraseando a lei de Parkinson, poderíamos dizer que "os programas tentem a expandir até ocupar toda a memória disponível para armazena-los". Idealmente, o que todo programador gostaria de ter à disposição é uma memória rápida e infinitamente grande que também fosse não-volátil, isto é, que não perdesse seu conteúdo quando a energia elétrica cai. E já que estamos divagando, por que também para que fosse bem barata? Infelizmente, a tecnologia ainda não oferece esse tipo de memória. A maioria dos computadores, portanto tem uma hierarquia de memória, com uma pequena quantidade de memória cache volátil, muito rápida e cara, alguns megabytes de memória principal volátil (RAM), de velocidade e preço médios, além de centenas ou milhares de megabytes de armazenamento em disco não-volátil, lento e barato. O trabalho do sistema operacional pe coordenar como essas memórias são utilizadas. A parte do sistema operacional que gerencia a hierarquia de memória é chamada gerenciador de memória. Seu trabalho é controlar que partes da memória estão em uso e que não estão, alocar memória para processos quando eles necessitarem e desalocar quando eles terminarem, e gerenciar a troca entre a memória principal e o disco quando a memória principal é muito pequena para armazenar todos os processos. (TANENBAUM e WODDHULL, 2000, p. 211) "A memória é fundamental para a operação de um sistema de computação moderno. A memória consiste em um grande vetor de palavras ou bytes, cada qual com seu próprio endereço. A CPU busca instruções da memória de acordo como o valor do contador de programa. Essas instruções também poderão causar carga e armazenamento em endereços de memória específicos." (SILBERSCHATZ et al., 2000, p. 179) Segundo Silberschatz et al. (2000) em um ciclo de execução padrão é procurar uma instrução na memória e traduzir essa instrução, podendo conter operações para buscar operandos na memória e após que for executada poderá voltar à memória. A unidade de memória visualiza apenas um fluxo de endereços, não conseguindo diferenciá-los e nem os definir. 17 Historicamente, a memória principal sempre foi vista como um recurso escasso e caro. Uma das maiores preocupações dos projetistas foi desenvolver sistemas operacionais que não ocupassem muito espaço de memória e, ao mesmo tempo, otimizassem a utilização dos recursos computacionais. Mesmo atualmente, com a redução de custo e conseqüente aumento da capacidade da memória principal, seu gerenciamento é um dos fatores mais importantes no projeto de sistemas operacionais. (MACHADO e MAIA, 2002, p. 155) 3.2 Monoprogramação Segundo Tanenbaum e Woodhull (2000) o modo mais simples de gerenciar memória é executar somente um programa de cada vez, dividindo a memória com o sistema operacional e este processo. Quando um sistema operacional segue as instruções acima ditas, somente um processo pode estar executando por vez na memória. Geralmente estes sistemas possuem um interpretador de comandos primitivo que recebe um comando para a tratar e fica em modo ocupado até acabar de realizar a tarefa, quando esta é concluída ele poderá tratar de outro comando que irá sobrepor a área de memória do primeiro não tendo a menor consideração com o que anteriormente estava naquela área. 3.3 Multiprogramação Conforme Oliveira et al. (2001) a multiprogramação permite que diversos processos sejam executados simultaneamente no computador com a divisão de tempo do processador. Para que esta divisão seja satisfatória, a gerencia de memória tem que permitir formas de compartilhamento de memória seguras e eficientes. 3.3.1 Partições de memória Como a memória possui um endereço linear de bytes e na multiprogramação vários programas podem estar na memória, é necessária uma divisão de memória em blocos estáticos ou dinâmicos. 18 3.3.1.1Fixa Segundo Tanenbaum e Woodhull (2000) em sistemas que compartilham tempo existem vários processos na memória e isso significa que quando um processo está ocioso esperando alguma interrupção de hardware, por exemplo, outro pode ocupar o espaço de processamento do processador. Percebe que nestes sistemas existe um grande aumento de processamento e uso dos recursos computacionais. Uma forma muito simples de atingir a multiprogramação é dividir toda a memória em pedaços, estes pedaços podem ter tamanhos iguais ou variar de tamanho também. A divisão da memória desta maneira é realizada no memento da carga do sistema.Os trabalhos que irão ser executados em uma determinada execução podem formar uma fila e serem executados um após um em uma determinada partição, ou em uma forma mais adequada e rápida: É organizada uma única fila com vários JOBS e na medida que os JOBS que estavam residentes na memória em trabalho vão terminando os processos da fila vão entrando na memória para serem executados. Este sistema de partições fixas foi implantado pela primeira vez no IBM OS/360 um computador de grande porte. (TANENBAUM e WODHULL, 2000) De acordo com Machado e Maia (2002) quando era necessário alterar o tamanho de uma partição no sistema de partições fixas, tinha-se que desativar o sistema e reiniciar ele passando uma nova configuração das partições. Nos primeiros sistemas os programas só funcionavam se fossem carregados em uma partição de memória X. Isso se devia a uma funcionalidade que ainda não estava implantada nos compiladores e montadores da época. Estes compiladores e montadores só geravam código absoluto (no processo de compilação os programas tinham seus códigos já predeterminados com determinados endereços.). Com a evolução surgiu o código realocável (as referências a endereços, são com base no início do código) que permitia que um programa fosse 19 executado a partir de qualquer endereço da memória. Para saber qual partição estava ocupada e qual não existia uma tabela de alocação, que tinha o índice da partição, o tamanho da página e o status dela, sendo livre ou não. (MACHADO e MAIA, 2002) Segundo Silberschatz et al. (2000), em um sistema com partições fixas cada partição poderá conter somente um processo em atividade, com isso o grau de programação é limitado ao número de partições. Quando um processo chega para memória deve ser procurado um bloco com tamanho compatível com ele, e assim ele é carregado. O sistema operacional ordena a fila de entrada dos processos com algum algoritmo de escalonamento. 3.3.1.2Dinâmica (troca) Segundo Tanenbaum e Woodhull (2000) neste sistema deve ser trazido um processo inteiro a memória e executar ele temporariamente e então o levar de volta ao disco. A grande diferença entre um sistema dinâmico de um com tabelas fixas é que o número, a posição e o tamanho das partições podem mudar e muito. Essa capacidade de mutação traz grandes melhoras no desempenho, porém fica muito mais difícil a manutenção desta memória que esta em uso. Quando a uma entrada e saída de processos da memória a uma tendência a ficarem pequenos espaços entre as partes, existe uma técnica chamada de compactação de memória que junta todo este espaço livre não utilizado em um só. Esta operação de compactação é muito demorada e geralmente não é implementada. Um processo pode crescer, alocando memória por conta própria, ocorrem problemas com isso: Se existe uma área livre na primeira posição após o processo ela é alocada pelo processo. Se a próxima lacuna contiver outro processo em execução todo o código do processo atual deve se mover para uma área suficientemente grande para poder comportar o processo e a quantidade de memória alocada por ele. Mas se não há nenhum tipo de memória livre o processo deve esperar ou ser eliminado. Se já é sabido que haverá possíveis 20 alocações de memória é recomendável alocar uma memória extra, para evitar futuras alocações. 3.3.1.2.1Gerenciamento de memória com Mapa de Bits Quando a memória for dinâmica o sistema operacional deve controlar ela, com o uso de mapas de bits a memória é dividida em X unidades que poderão receber os bits 0 para não utilizada e um para utilizada. (TANENBAUM e WOODHULL, 2000) "O tamanho da unidade de alocação é uma importante questão de projeto. Quanto menor a unidade de alocação maior o mapa de bits." (TANENBAUM e WOODHULL, 2000, p. 216) 3.3.1.2.2Gerenciamento de memória com Listas Encadeadas Mantém armazenados em uma lista os segmentos alocados e os livres de memória. Cada item da lista é um espaço de memória vazio ou cheio. Por isso existem algoritmos para adquirir o melhor e mais rápido espaço de memória. (TANENBAUM e WOODHULL, 2000) Segundo Silberschatz et al. (2000) existem dois tipos de fragmentação: • Interna: Conforme os processos são carregados e descarregados da memória o espaço livre da memória fica "picotado" em pequenas partes, a fragmentação externa aparece quando a espaço disponível na memória mas ele está fragmentado. • Externa: Se a memória for dividida em tamanhos fixos e alocar unidades de tamanho de bloco, o espaço restante de um conteúdo que esta na memória é a fragmentação externa. "Na alocação particionada dinâmica ou variável, foi eliminado o conceito de partições de tamanho fixo. Neste esquema, cada programa utilizaria o espaço necessário, tornando essa área sua partição. Como os programas utilizam apenas o espaço de que necessitam, no esquema de 21 alocação particionada dinâmica o problema de fragmentação interna não ocorre." (MACHADO e MAIA, 2002, p 162) 3.3.2 Swapping Segundo Machado e Maia (2002) a técnica de swapping foi criada para tentar suprir o problema de falta de memória principal. O ciclo básico de um processo é ficar na memória principal até o fim de sua execução, até nos momentos em que o processo ficava ocioso esperando por uma operação de leitura ou gravação. No swapping o processo que está pouco utilizado é passado para a memória secundaria (swap out) normalmente sendo um disco rígido. Após algum tempo o processo é carregado novamente para a memória principal (swap in) para continuar sua execução. O algoritmo usado para retirar um processo da memória deve ter como prioridade retirar aquele que está com menores chances de ser posto em execução. Para a técnica de swapping ser posta em execução deve-se ter em no sistema um loader que faça a realocação de programas. A realocação dinâmica é feita com um registrador especial com o nome de registrador de alocação. Quando o programa é carregado na memória este registrador recebe o endereço inicial do programa. Sempre que ocorrer uma chamada a um endereço, o endereço que esta na instrução será somado ao conteúdo do registrador, gerando um endereço físico. O uso do swapping permite um maior uso dos recursos computacionais, mas apresenta um grande problema que é o elevado tempo de operações de entrada/saída (swap in/out). (MACHADO e MAIA, 2002) Normalmente, um processo que é descarregado será carregado para o mesmo espaço de memória que ocupava anteriormente, Essa restrição é determinada pelo método de resolução de endereço. Se a resolução for feita no momento de carga ou montagem, o processo não poderá ser movido para posições diferentes. Se a resolução em tempo de execução estiver sendo usada, é possível passar um processo para um espaço de memória diferente, porque os endereços físicos são calculados durante o tempo de execução. (SILBERSCHATZ et al., 2000, p. 184) 22 Segundo Tanenbaum e Woodhull (2000) o procedimento de troca padrão é usado em poucos sistemas, pois ele utiliza um tempo grande de troca não sendo aceito para um sistema de gerencia de memória. Versões modificadas do swapping são usadas em outros sistemas como o UNIX. 3.3.3 Memória virtual 3.3.3.1Introdução Segundo Tanenbaum e Woodhull (2000) surgiu uma época em que os programas ficaram tão grandes que não eram capazes de serem carregados na memória. Tempos depois apareceu a memória virtual esta técnica permite que os programas podem ter um tamanho maior que a memória física e mesmo assim serem executados. A memória virtual se adapta muito bem em um sistema de multiprogramação, pois possibilita que múltiplos pedaços de programas sejam executados na memória. A memória virtual é uma técnica que permite a execução de processos que podem não estar inteiramente na memória. A principal vantagem vivível desse esquema é que os programas podem ser maiores do que a memória física. Além disso, ele abstrai a memória principal em um vetor extremamente grande e uniforme de armazenamento, separando a memória lógica conforme vista pelo usuário da memória física. Essa técnica libera os programadores da preocupação com as limitações de memória. A memória virtual não é fácil de implementar, entretanto, e pode diminuir muito o desempenho se for utilizada sem o devido cuidado. (SILBERSCHATZ et al, 2000, p. 210) Segundo Machado e Maia (2002) a memória virtual é uma técnica sofisticada e poderosa de gerência de memória, as memórias principal e secundária são unidas deixando o usuário com uma ilusão de que existe uma memória muito maior que a física disponível, os endereços de memória são abstratos aos endereços físicos de memória principal. A memória virtual esta muito ligada à arquitetura do computador, pois com hardware de memória virtual o desempenho fica muito mais rápido. 23 3.3.3.2Overlay Segundo Tanenbaum e Woodhull (2000) overlays são pedaços de um programa, a execução do overlay começa pelo zero e quando este termina outros são chamados. Os overlays são mantidos no disco e são manipulados dinamicamente pelo sistema operacional do disco para a memória e da memória para o disco. Para que um processo possa ser maior do que a quantidade de memória alocada por ele, podemos usar overlays. A idéia do overlay é manter na memória apenas as instruções e dados que são necessários em determinado momento. Quando outras instruções são necessárias, elas são carregadas no espaço que foi anteriormente ocupado por instruções que não são mais necessárias. (SILBERSCHATZ et al., 2000, p. 183) Figura 5: Overlay para um montador de dois passos (SILBERSCHATZ et al., 2000) Segundo Machado e Maia (2002) os programas eram uma vez limitados ao tamanho da memória principal disponível, uma forma para contornar isso foi dividir o programa em módulos na memória de que eles sejam independentes e sejam executados em um mesmo endereço de memória. 24 "A definição das áreas de overlay é função do programador, através de comandos específicos da linguagem de programação utilizada. O tamanho de uma área de overlay pe estabelecido a partir do tamanho do maior módulo." (MACHADO e MAIA, 2002, p. 158) “Uma das primeiras tentativas de se usar armazenamento em disco para armazenar memória principal fazia o uso de overlays, nos quais o programa em execução sobrescreve seu próprio código com outro código quando necessário.” (MURDOCCA e HEURING, 2000, p. 249) 3.3.3.3Paginação Segundo Tanenbaum e Woodhull (2000) toda a área de endereços virtuais é dividida em páginas e as unidades de memória física são chamadas de molduras de página, as molduras e as páginas devem sempre ter o mesmo tamanho. 25 Figura 6: A relação entre endereços virtuais e endereços físicos de memória (TANENBAUM e WOODHULL, 2000) A paginação é um esquema que permite que o espaço de endereçamento físico de um processo seja não-continuo. A paginação evita o problema de ajustar os pedaços de memória dos mais diversos tamanhos no armazenamento auxiliar, um problema sério que afetou a maioria dos esquemas de gerência de memória anteriores. Quando alguns fragmentos de código ou dados que residem na memória principal precisam ser descarregados (operação de swap out), deve haver espaço disponível no armazenamento auxiliar. Os problemas de fragmentação discutidos em relação à memória principal também prevalecem com o armazenamento auxiliar, exceto pelo fato de que o acesso é muito mais lento, por isso é impossível fazer a compactação. Devido às vantagens em relação aos métodos anteriores, a paginação em suas muitas formas é utilizada com freqüência em muitos sistemas operacionais.” (SILBERSCHATZ et al., 2000, p 189) 26 A memória virtual por paginação é a técnica de gerência de memória onde o espaço de endereçamento virtual e o espaço de endereçamento real são divididos em blocos de mesmo tamanho chamados páginas. As páginas no espaço virtual real são chamadas de páginas reais ou frames. (MACHADO e MAIA, 2002, p. 176) Paginação é uma forma de sobreposição automática que é gerenciada pelo sistema operacional. O espaço de endereçamento é particionado em blocos de tamanhos iguais chamados de páginas. Páginas são normalmente de um tamanho que é uma potência de 2 tal como 2 na 10 = 1024 bytes. Paginação faz com que a memória física apareça maior do que realmente é mapeando o espaço de endereçamento de memória física a um espaço de endereçamento de memória virtual, que é normalmente armazenado em disco. (MURDOCCA e HEURING, 2000, p.249) 3.3.3.4Tabelas de páginas Segundo Tanenbaum e Woodhull (2000) um endereço virtual tem as seguintes partes: número da página virtual e deslocamento. O primeiro item é um endereço de localização daquela página na tabela de páginas virtuais. Usando este endereço virtual também se pode achar o número da moldura de página correspondente a aquele endereço. O objetivo da tabela de páginas é através do endereço virtual mapear uma moldura de página. Cada sistema operacional tem seus próprios métodos para armazenar tabelas de página. A maioria aloca uma tabela de página para cada processo. Um ponteiro para a tabela de página é armazenado com outros valores de registrador (como o contador de instruções) no bloco de controle do processo. Quando o dispatcher é informado que determinado processo deve ser iniciado, ele deverá recarregar os registradores de usuário e definir os valores de tabela da página de hardware corretos a partir da tabela de página de usuário armazenada. (SILBERSCHATZ et al., 2000, p. 193) Segundo Machado e Maia (2002) todo processo tem uma tabela de páginas própria e cada página virtual tem uma entrada na tabela de páginas. Cada entrada na tabela de páginas possui informações como: bit de validade (para dizer se a página esta ou não na memória principal). Toda vez que o programa em execução chama um endereço virtual, é verificado se este endereço está atualmente na memória ou não. Se a página referenciada não se encontrar na memória principal é gerada uma interrupção de falta de página (page fault) o sistema operacional deve 27 tratar disso pegando a página na memória secundaria e a enviando até a memória principal. 3.3.3.4.1Tabela de página multinível De acordo com Tanenbaum e Woodhull (2000) para evitar o incomodo problema de ter grandes tabelas de memória o tempo todo, alguns computadores usam tabelas de páginas de multinível. Na paginação multinível todas as tabelas de página não são mantidas na memória, só ficam nela aquelas páginas que o processo esta usando ou que são de extra importância. 28 Figura 7: (a) Um endereço de 32 bits com dois campos de tabela de páginas. (b) Tabelas de páginas de dois níveis (TANENBAUM e WOODHULL, 2000) Um endereço em multinível é dividido em três campos: PT1: Referencia-se a tabela de página de primeiro nível e esta tem ligações para a tabela de páginas de segundo nível. PT2 Esta ligada à tabela de páginas de segundo nível e esta tem a função de localizar um número de moldura de página nela mesma. Deslocamento: Base de localização e movimento da página. Conforme Silberschatz et al. (2000) é possível usar varias tabelas de página em um esquema de paginação. Mesmo usando vários níveis na pesquisa de tabela a um aumento pouco significativo de acesso à memória. 29 "...A grande vantagem da paginação em múltiplos níveis é que apenas estão residentes na memória principal as tabelas realmente necessárias aos processos, reduzindo, dessa forma o espaço ocupado na memória." (MACHADO e MAIA, 2002, p. 193) 3.3.3.4.2TLB Segundo Tanenbaum e Woodhull (2000), manter várias tabelas de página na memória não era produtivo pois causava um enorme impacto negativo no desempenho. Foi criado um dispositivo de hardware que mapeia endereços virtuais em físicos sem passar pela memória, o nome deste dispositivo pe TLB ou memória associativa. Ele fica localizado dentro da MMU e consistem em um número pequeno de entradas. Estas entradas possuem campos com informações como número da página, status de modificação, bits de proteção e moldura de página física que o processo esta. O funcionamento da TLB se da seguinte forma: Quando chega um endereço ele é verificado se a página virtual está no TLB é verificado se a permissão de acesso a página e ela é procurada se ele não estiver na TLB uma das entradas atuais dela é retirada e esta entra. (TANENBAUM e WOODHULL, 2000) A gerencia de memória virtual utiliza a técnica de mapeamento para traduzir endereços virtuais em endereços reais, podem, o mapeamento implica pelo menos dois acessos a memória principal: o primeiro a tabela de páginas e o outro a própria página. Sempre que um endereço virtual precisa ser traduzido a tabela de mapeamento deve ser consultada para se obter o endereço do frame e, posteriormente , acessar o dados na memória principal. (MACHADO e MAIA, 2002, p. 194) Segundo Machado e Maia (2002) o funcionamento da TLB é como se fosse uma memória cache, pois tem um espaço pequeno e mantém as ultimas entradas. A TLB e fundamental para reduzir os acessos nos sistema de memória virtual. 30 3.3.3.4.3Tabelas de páginas invertidas Segundo Tanenbaum e Woodhull (2000) as tabelas de página tradicionais necessitam uma entrada por página virtual manter estas páginas na memória consome espaço e à medida que se aumenta os bits dos computadores este espaço expande constantemente. Segundo Silberschatz et al. (2000), para contornar o incomodo de manter várias páginas na memória pode-se usar uma tabela de página invertida. Nesta tabela existe uma entrada para cada página real de memória. Cada uma das entradas se orienta por um endereço virtual que pe armazenado naquela posição rela da memória. Todas as entradas da tabela de páginas invertidas são um par de (id do processo e número da página) Este método de paginas invertidas reduz a quantidade de memória usada para armazenar de dados. A tabela de páginas invertidas possui somente endereços físicos, como a pesquisa por páginas é feita com endereços lógicos fica uma tanto demorada a pesquisa de páginas. (SILBERSCHATZ et al., 2000) 31 Figura 8: Tabela de página invertida (SILBERSCHATZ et al., 2000) 3.3.3.5Substituição de páginas Quando ocorre uma falha de página o sistema operacional precisa escolher uma página para remover da memória e dar lugar para a página que precisa ser carregada, se a página a ser removida tiver sido movida enquanto na memória ela deve ser regravada no disco para atualizar a cópia em disco, se, entretanto a página não foi alterada(p. ex. uma página contém texto de programa.) a cópia em disco já esta atualizada então nenhuma regravação é exigida. A página a ser lida simplesmente subscreve a página sendo expulsa. Embora seja possível selecionar aleatoriamente uma página para remover em cada falha de página, o desempenho do sistema será muito melhor se uma página que não é intensamente utilizada for escolhida. Se uma página altamente utilizada for removida provavelmente ela precisara ser trazida de volta em breve, o que resulta em sobrecarga externa. (TANENBAUM e WOODHULL, 2000, p. 225) A substituição de página assume a seguinte abordagem. Se um quadro esta livre, encontramos um que não esta sendo usado no momento e o liberamos. Podemos libertar um quadro gravando seu conteúdo no espaço de swap e alterando a tabela de página(e todas as outras tabelas) para indicar que a página não esta mais na memória. Agora podemos usar o quadro liberado para armazenar a página para a qual ocorreu a falta no processo. (SILBERSCHATZ et al., 2000, p. 218) "A melhor estratégia de substituição de páginas seria aquela que escolhesse um programa que não fosse mais utilizado no futuro ou levasse 32 mais tempo para ser novamente referenciado." (MACHADO e MAIA, 2002, p. 185) 3.3.3.6Swapping na memória virtual Segundo Machado e Maia (2002) o uso da técnica de swapping faz aumentar o número de processos que usam a memória principal, trazendo assim uma maior multiprogramação no sistema. Se a memória principal esta cheia e chegam novos processos para serem executados, o sistema tem que usar a técnica de swapping para reunir os processos que iram sair da memória principal indo para a memória secundária (swap out), nesta os processos selecionados ficaram em um arquivo swap. Quando os processos que estão no arquivo swap precisarem ir para a memória principal ocorre à operação de swap in para transferir estes processos. Existem vários quesitos a serem seguidos para perceber qual processo saí da memória. A base desta escolha é selecionar os processos que dificilmente são executados. O arquivo swap é compartilhado por todos os processos que estão sendo executados no ambiente. Quando um processo é criado, o sistema reserva um espaço no arquivo swap para o processo. Da mesma forma. quando um processo é eliminado o sistema libera a área alocada. Em alguns sistemas operacionais, o arquivo de swap é, na verdade, uma área em disco reservada exclusivamente para esta função. Independentemente da implementação, o arquivo de swap deve oferecer o melhor desempenho possível para as operações de swapping. (MACHADO e MAIA, 2002, p 203) 33 Figura 9: Swapping em memória virtual (MACHADO e MAIA, 2002) 34 3.3.3.7Segmentação Segundo Tanenbaum e Woodhull (2000) um conjunto de endereços completamente independentes são chamados de segmentos. Os segmentos têm uma seqüência linear de 0 até N, estes segmentos podem ter um comprimento também de 0 até N. O comprimento dos segmentos pode variar durante a sua execução, por exemplo um segmento de pilha muda seu tamanho quando algo é retirado ou colocado na pilha. O endereço em uma memória segmentada é dividido em duas partes (número do segmento e endereço dentro do segmento). (TANENBAUM e WOODHULL, 2000) Figura 10: Uma memória segmentada permite que cada tabela cresça ou escolha independentemente das outras tabelas (TANENBAUM e WOODHULL, 2000) Segundo Silberschatz et al. (2000) um usuário ou programador do sistema não imagina memória como um vetor linear de bytes e sim com uma coleção de segmentos com tamanhos diversos. 35 "A segmentação é um esquema de gerência de memória que oferece suporte a essa visão de usuário da memória. Um espaço de endereçamento lógico é uma coleção de segmentos. Cada segmento tem um nome e tamanho. Os endereços especificam o nome do segmento e o deslocamento dentro do segmento. O usuário especifica, portanto, cada endereço por duas quantidades: um nome de segmento e um deslocamento." (SILBERSCHATZ et al., 2000, p. 201) Figura 11: Visão de usuário de um programa (SILBERSCHATZ et al., 2000) "Memória virtual por segmentação é a técnica de gerência de memória onde o espaço de endereçamento virtual é dividido em blocos de tamanhos diferentes chamados segmentos. Na técnica de segmentação, um programa é dividido logicamente em sub-rotinas e estruturas de dados, que são alocadas em segmentos na memória principal." (MACHADO e MAIA, 2002, p. 197) De acordo com Machado e Maia (2002) na segmentação ocorre uma ligação entre a lógica do programa e sua alocação na memória principal. Geralmente os segmentos são criados pelo compilador assim sendo os segmentos podem ter procedimentos, funções, pilhas e variáveis. Os segmentos são mapeados através de uma tabela de mapeamento de 36 segmentos. Um grande trunfo da segmentação sobre a paginação é a facilidade de tratar estruturas de dados dinâmicas. Na segmentação os segmentos referenciados são carregados na memória, assim pode haver desperdício de memória, se o programa não for dividido em partes. Na paginação ocorre fragmentação externa, pois pode haver áreas livres entre processos. "...Segmentação divide o espaço de endereçamento em segmentos, que podem ter tamanho arbitrário. Cada segmento é o seu próprio espaço de endereçamento unidimensional. Isso permite que tabelas, pilhas e outras estruturas de dados sejam mantidas como entidades lógicas que crescem sem trombar umas nas outras." (MURDOCCA e HEURING, 2000, p. 253) 3.3.3.8Thrashing Segundo Machado e Maia (2002) thrashing é o grande movimento de páginas ou segmento entre a memória principal e a memória secundária. Na paginação o thrashing pode ocorrer por haver um grande número de page fault de um processo ou se existir mais processos batalhando por memória principal que o espaço disponível. Na segmentação ocorre thrashing, pois existe grande transferência de segmentos, devido à divisão do programa. Outro caso é quando há mais processo batalhando por memória principal que espaço em disco. Segundo Silberschatz et al. (2000) o thrashing trás grandes problemas de desempenho, à medida que a utilização da CPU aumenta, sobe o uso da multiprogramação até chegar a um limite, quando este limite é atingido a utilização da CPU caí drasticamente, tendo assim o sistema ter que diminuir a multiprogramação. Para evitar a ocorrência do thrashing tem que ser fornecido ao processo um número maior de quadros do ele precisa. 37 Figura 12: Thrashing (SILBERSCHATZ et al., 2000) 38 4 ALGORITMOS 4.1 Alocação memória 4.1.1 Conceito Segundo Machado e Maia (2002) os sistemas operacionais usam várias formas para ver qual área de memória livre um programa poderá ser executado. Não importando o algoritmo o sistema possui uma lista de áreas livres disponíveis. "Quando os processos e as lacunas são mantidos em uma lista classificada por endereço, vários algoritmos podem ser utilizados para alocar memória para um processo recentemente criado ou trocado para a memória." (TANENBAUM e WOODHULL, 2000, p.216) Segundo Silberschatz et al. (2000), existem várias soluções para contornar o problema da fragmentação de memória dinâmica. Uma delas é pesquisar na memória para ver qual bloco deve ser alocado. 4.1.2 First-fit "Aloca o primeiro bloco de memória grande o suficiente. A busca pode começar no início do conjunto de blocos ou no ponto em que a pesquisa first-fit anterior terminou. Podemos interromper a busca assim que encontramos um bloco de memória grande o suficiente." (SILBERSCHATZ et al., 2000, p. 188) "Na estratégia first-fit, a primeira partição livre de tamanho suficiente para carregar o programa é escolhida. Nesse algoritmo, a lista de áreas livres está ordenada crescentemente por endereços. Como o método tenta primeiro utilizar as áreas livres de endereços mais baixos, existe uma 39 grande chance de se obter uma grande partição livre nos endereços de memória mais altos." (MACHADO e MAIA, 2002, p. 167) "O algoritmo mais simples é chamado de algoritmo do primeiro ajuste. O gerenciador de memória varre toda a lista de segmentos até localizar uma lacuna que seja suficientemente grande. A lacuna, então, é dividida em dois pedaços, um para o processo e um para a memória não-utilizada, exceto no improvável caso de um ajuste exato." (TANENBAUM e WOODHULL, 2000, p. 216) 4.1.3 Best-fit "Aloca o menor bloco de memória grande o suficiente. É preciso procurar na lista inteira, a menos que a lista seja ordenada por tamanho. Essa estratégia gera o menor bloco de memória restante." (SILBERSCHATZ et al., 2000, p. 188) Na estratégia best-fit, a melhor partição é escolhida, ou seja, aquela em que o programa deixa o menor espaço sem utilização. Nesse algoritmo, a lista de áreas livres está ordenada por tamanho, diminuindo o tempo de busca por uma área desocupada. Uma grande desvantagem desse método é conseqüência do próprio algoritmo. Como é alocada a partição que deixa a menor área livre, a tendência é que cada vez mais a memória fique com pequenas áreas não-contíguas, aumentando o problema da fragmentação. (MACHADO e MAIA, 2002, p. 165) "Pesquisa na lista inteira e pega a menor lacuna que seja adequada. Antes de dividir uma lacuna grande que talvez seja necessária mais tarde, o melhor ajuste tenta localizar uma lacuna é próxima do tamanho real necessário." (TANENBAUM e WOODHULL, 2000, p. 217) 4.1.4 Worst-fit "Aloca o maior bloco de memória. Mais uma vez, é preciso procurar na lista inteira, a menos que ela esteja classificada por tamanho. Essa estratégia gera o maior bloco de memória restante, que pode ser mais útil 40 do que o bloco restante menor de uma abordagem best-fit." (SILBERSCHATZ et al., 2000, p. 188) "Na estratégia worst-fit, a pior partição é escolhida, ou seja, aquela em que o programa deixa o espaço sem utilização. Apesar de utilizar as maiores partições, a técnica de worst-fit deixa espaços livres maiores que permitem a um maior número de programas utilizar a memória, diminuindo o problema da fragmentação." (MACHADO e MAIA, 2002, p. 165) "Sempre pegar a maior lacuna disponível, de modo que a lacuna resultante seja suficientemente grande para ser útil." (TANENBAUM e WOODHULL, 2000, p. 217) 4.1.5 Next-fit "Ele funciona da mesma maneira que o primeiro ajuste, exceto que monitora a posição em que ele está sempre que encontra uma lacuna adequada. Da próxima vez que é chamado para localizar uma lacuna, ele começa pesquisando na lista a partir do lugar que ele deixou da última vez, em vez de sempre a partir do começo." (TANENBAUM e WOODHULL, 2000, p. 217) 4.1.6 Quick-fit "Mantém listas separadas para alguns tamanhos exigidos mais comuns." (TANENBAUM e WOODHULL, 2000, p. 217) Este algoritmo possui poucas referências pois é pouco utilizado. 41 4.2 Algoritmos de substituição de páginas 4.2.1 LRU "O algoritmo LRU seleciona a página na memória principal que está a mais tempo sem ser referenciada. Se considerarmos o princípio da localidade, uma página que não foi utilizada recentemente provavelmente não será referenciada novamente em um futuro próximo." (MACHADO e MAIA, 2002, p. 187) De acordo com Silberschatz et al. (2000) o LRU junta a cada página uma referencia de uma data, está data diz respeito à última vez que a página foi usada. No momento em que uma página necessite ser trocada, a página que será retirada da memória será aquela que tiver a menor data de acesso. A implementação do LRU exige uma forte ajuda do hardware. Implementações viáveis: • Contadores: Neste esquema existem dois campos. Um com a página e outro com um contador, quando a página é usada este contador cresce, substituindo o valor antigo. A página a ser substituída será aquela com o menor contador. • Pilha: Existe um vetor com várias entradas, cada uma destas entradas conterá uma página. Esse array é classificado de uma forma que as páginas mais usadas fiquem sempre no topo da pilha. Nenhuma implementação de LRU seria viável se não existisse uma assistência de hardware e registradores TLB. (SILBERSCHATZ et al., 2000) Embora o LRU seja teoricamente realizável, ele não é barato. Para implementar completamente o LRU, é necessário manter uma lista encadeada de todas as páginas na memória, com as páginas mais recentemente utilizadas na frente e as menos recentemente utilizadas no fundo. A dificuldade é que a lista deve ser atualizada a cada referência de memória. A operação de localizar uma página na lista, excluí-la e, então, movê-la para a frente consome muito tempo, mesmo em hardware 42 (supondo que tal hardware pudesse ser construído). (TANENBAUM e WOODHULL, 2000, p. 228) 4.2.2 LFU "O algoritmo de substituição de página menos freqüentemente usada Least Frequently Used (LFU) requer que a página com a menor contagem serja substituída. O motivo para essa seleção pe que uma página muito usada deve ter uma contagem de referência alta. Esse algoritmo enfrenta o seguinte problema: uma página é muito usada durante a fase inicial de um processo,mas depois nunca mais é usada. Como ele foi muito utilizada, possui uma alta contagem e permanece na memória embora não seja mais necessária. Uma solução é deslocar as contagens para a direita em 1 bit em intervalos regulares, formando uma contagem de uso médio com decaimento exponencial." (SILBERSCHATZ et al., 2000, p. 226) "O algoritmo LFU seleciona a página menos referenciada, ou seja, o frame menos utilizado. Para isso, é mantido um contador com o número de referências para cada página na memória principal. A página que possuir o contador com o menor número de referências será escolhida, ou seja, o algoritmo evita selecionar páginas que são bastante utilizadas." (MACHADO e MAIA, 2002, p. 187) 4.2.3 NUR Segundo URI, o NUR utiliza como critério para substituição de páginas o acesso recente à página, ou seja, é substituída a página que a mais tempo não foi acessada. Um argumento para o NUR trabalhar dessa forma é que as páginas que não foram acessadas no passado provavelmente não serão usadas no futuro. De acordo com o COTUCA, o NUR se baseia em excluir da memória a página mais velha em termos de uso. Para avaliar qual página esta apta a sair da memória, o NUR trabalha com dois bits, um indicando o estado de modificação(M) e o outro é o bit de referência(R). O algoritmo classifica as páginas em 4 tipos: 43 Tabela 1: Classificação das páginas. Classe 0 1 2 3 Bit Referência Não Não Sim Sim Bit Modificação Não Sim Não Sim Quando ocorrer a falta de páginas o algoritmo retira as páginas na ordem cresceste da classe, ou seja, primeiro todas as páginas de bit 0, se não haver nenhuma página na classe 0 ele vai para a classe 1 e assim sucessivamente. (COTUCA) 4.2.4 NFU Segundo o COTUCA, o algoritmo NFU é uma implementação do LRU baseada em software. O funcionamento dele é o seguinte: Existirá um contador associado a cada página, esse contador é movimentado a cada interrupção de tempo. Quando acontecer a falta de páginas, será eliminada da memória a página com o maior valor do contador. 4.2.5 MRU Segundo Tanenbaum (2003) este algoritmo chega perto do desempenho do algoritmo de substituição de páginas Ótimo. Ele se baseia no principio de que a página com maior tempo sem uso deve ser a escolhida a ser substituída da memória. Para implementar o MRU é gasto muitos recursos computacionais, pois é necessário ter uma lista com todas as páginas da memória. (TANENBAUM, 2003) Existem duas maneiras aplicáveis de se implementar o LRU por software: • Contador: Utiliza um contador de 64 bits que conterá o número de uso de cada página da memória. Dessa forma quando for feita a escolha 44 para a página a ser retirada da memória será analisada a página com o menor valor deste contador. (TANENBAUM, 2003) • Matriz de bits: Esta estrutura contém as listas e colunas com páginas de memória. Sempre que uma página é referenciada a linha correspondente da matriz é preenchida com o valor 1 e a coluna fica com o valor 0. Na escolha da página a ser substituída será considerado o menor valor como critério de seleção. (TANENBAUM, 2003) 4.2.6 Ótimo Segundo Silberschatz et al. (2000) o algoritmo ótimo possuí a menor taxa de faltas de páginas de todos os algoritmos e nunca sofrerá a anomalia de Belady. Sua regra é substituir a página que não será usada até o fim de um período. O ótimo promete a menor taxa de falta de páginas em um número de quadros. O algoritmo ótimo é difícil de se implementar pois tem que se conhecer a string do futuro. (SILBERSCHATZ et al., 2000) Segundo Tanenbaum e Woodhull (2000), o algoritmo de substituição de páginas ótimo é impossível de implementar. O sistema operacional não consegue prever qual página virá no futuro. Mas para motivo de testes você pode utilizar, o algoritmo ótimo em um simulador, isso é útil para medir o desempenho de novos algoritmos. "Se um sistema operacional alcançar um desempenho de, digamos, somente 1% pior do que o algoritmo ótimo, o esforço gasto em pesquisar um melhor algoritmo resultará em uma melhoria de 1% no máximo." (TANENBAUM e WOODHULL, 2000 p. 226) O algoritmo ótimo seleciona para substituição uma página que não será mais referenciada no futuro ou aquela que levará o maior intervalo de 45 tempo para ser novamente utilizada. Apesar de este algoritmo garantir as menores taxas de paginação para os processos, na prática é impossível e ser implementado, pois o sistema operacional não tem como conhecer o comportamento futuro das aplicações. Essa estratégia é utilizada apenas como modelo comparativo na análise de outros algoritmos de substituição. (MACHADO e MAIA, 2002, p. 186) 4.2.7 FIFO No algoritmo FIFO, a página que primeiro foi utilizada será a primeira a ser escolhida, ou seja, o algoritmo seleciona a página que está a mais tempo na memória principal. O algoritmo pode ser implementado associando-se a cada página o momento em que foi carregada para a memória ou utilizando-se uma estrutura de fila, onde as páginas mais antigas estão no início e as mais recentes no final. (MACHADO e MAIA, 2002, p. 186) "...Quando aplicado a estoques, FIFO talvez remova produtos como vaselina para bigodes, mas talvez também remova farinha, sal ou manteiga, Quando aplicado a computadores, o mesmo problema surge. Por essa razão FIFO em sua forma pura é raramente utilizado." (TANENBAUM e WOODHULL, 2000, p. 227) O algoritmo de substituição de página mais simples é um algoritmo FIFO. Esse algoritmo associa a cada página o instante em que a página foi levada para a memória. Quando é preciso substituir uma página, a página mais antiga é trazida. Podemos criar uma fila FIFO para manter todas as páginas na memória. Substituímos a página que estiver no início da fila. Quando uma página é movida para a memória, ela é inserida no final da fila. (SILBERSCHATZ et al., 2000, p. 221) Segundo Silberschatz et al. (2000) o algoritmo FIFO é fácil de entender e implementar, porém seu desempenho é muito duvidoso. Este algoritmo é bastante venerável a anomalia de Belady (Quando a taxa de falta de páginas aumenta a medida que o número de quadros alocados aumenta.) 4.2.8 SC Uma modificação simples do FIFO evita o problema de jogar fora uma página intensamente utilizada pe inspecionar o bit R da página mais antiga. Se for 0, a página será antiga ou não-utilizada, então, ela é substituída imediatamente. Se o bit R for 1, o bit será limpo, a página será colocada no fim da lista de páginas e seu tempo de carga é atualizado como se acabasse de chegar na memória. Então a pesquisa contínua. (TANENBAUM e WOODHULL, 2000, p. 227) 46 De acordo com, Silberschatz et al (2000) o algoritmo segunda chance é um algoritmo FIFO adaptado com um campo extra, esse campo pode conter o bit 0 ou 1. Se o bit for 0 a página, referenciada é substituída. Caso contrário se for 1, está página recebe uma segunda chance, ou seja, seu bit é modificado para 0 e ela é passada para o final da fila. Caso ocorra um momento em que todos os bits da página forem 1, o algoritmo segunda chance se transforma em um tradicional FIFO eliminando a primeira página da fila. 4.2.9 CLOCK Conforme Tanenbaum e Woodhull (2000) a substituição de páginas relógio ou clock mantém todas as páginas em uma lista circular, com um recurso de ponteiro posicionado na página mais antiga. Se ocorrer uma falta de página, a página apontada pelo ponteiro é analisada, se seu bit de utilização for 0, a página é retirada da memória , uma nova página será posta e o ponteiro fará um movimento a frente. Caso o bit seja 1, esse bit é setado para 0 e o ponteiro avança uma posição. 4.2.10WSCLOCK De acordo com Tanenbaum (2003), o WSCLOCK é baseado no algoritmo Clock, tem uma fácil implementação e bons desempenhos. Este algoritmo trabalha com uma lista circular e um ponteiro que fica sempre posicionado no último movimento dele. Nos itens desta lista existe um campo com um bit. Se esse bit for igual a 1 a página foi referenciada durante a interrupção do relógio atual, caso o bit for 0, a página pode ser substituída. 4.2.11PFF Segundo SEDMAK (1997) o ideal dos sistemas seria se o total de falta de páginas fosse sempre 0, assim uma série de processamentos seriam 47 evitados, melhorando muito a performance do sistema. Infelizmente este zero das páginas não pode ser praticado. O algoritmo PFF trata uma quantidade de não-zero de faltas de páginas como sendo um ideal. A freqüência de falta de páginas (PFF) determina um monitoramento das taxas de faltas de páginas. Se a talha de falta de página for maior que um ponto P, o alocamento das páginas será aumentado. Caso contrário, se o número de faltas de páginas for mais baixa que um ponto inicial, o alocamento das páginas será diminuído. (SEDMAK, 1997) "No instante t(rk) da falta, a distância temporal Df até a falta anterior é comparada com 1/P. Se Df £ 1/P nenhuma página é substituída, ao contrário, a alocação de memória do programa é aumentada de uma página. Se Df > 1/P, as páginas não referenciadas no intervalo Df (se houver alguma) são retiradas da memória." (CIC) Segundo MCCRAW, os vários algoritmos de substituição de páginas podem também ser usados para monitorar a taxa de falta de páginas que ocorre em um determinado programa. O PFF tem limitação quanto à aplicação, por exemplo, um banco de dados causa uma grande freqüência de falta de páginas. Neste esquema programa não tem benefício em deixar registradas páginas. As fortes mudanças de troca de páginas resultam em desperdício de memória. (MCCRAW) 4.2.12LIRS “Este algoritmo utiliza os intervalos de acessos entre diferentes blocos em seqüência para determinar a relevância dos blocos. O algoritmo funciona da maneira contrária ao algoritmo LRU, que utiliza o tempo de último acesso a um bloco para determinar a relevância do mesmo. O 48 algoritmo LIRS leva em conta os intervalos de acesso aos blocos para determinar a relevância dos mesmos.” (DODONOV) 4.2.13ARC Segundo Megiddo e Modha (02/2003) a memória cache é fundamental para os computadores modernos da atualidade. Para controlar a cache de uma forma produtiva existem os algoritmos de cache, os progressos destes algoritmos tem afeitado muito o desempenho dos computadores. O algoritmo ARC possui as seguintes características: • Fácil implementação; • Tem baixo overhead, respondendo rapidamente a mudanças; • Sua execução independe do tamanho da cache; • O ganho de desempenho em relação ao LRU existe; A política geral de funcionamento do ARC é ter uma grande falta de páginas e possuir um baixo overhead. (MEGIDDO e MODHA, 02/2003) De acordo com Megiddo e Modha (03/2003) o ARC funciona da seguinte forma: Ele mantém duas listas LRU de páginas. Uma lista contém páginas que foram visitadas somente uma vez recentemente. E a outra lista contém páginas que foram acessadas ao menos duas vezes recentemente. Deve-se pensar no ARC imaginando duas tabelas, uma de propósito recentemente visitada e a outra de propósito freqüência de visitas. "ARC é fácil de implementar e seu tempo de execução por pedido é independente do tamanho da cache." (MEGIDDO e MODHA, 2004) Megiddo e Modha (08/2003) realizaram uma série comparando o ARC com o LRU que resultaram na tabela abaixo: de testes 49 Tabela 2: Resultados de testes com o algoritmo ARC. (MEGIDDO e MODHA, 08/2003) • Trabalho Tamanho LRU ARC carregado P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 ConCat Merge(P) DS1 SPC1 S1 S2 S3 Merge(S) (MB) 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 128 1024 4096 2048 2048 2048 4096 (% Faltas) 16.55 18.47 3.57 5.24 6.73 4.24 3.45 17.18 8.28 2.48 20.92 8.93 7.83 15.73 14.38 38.05 11.65 9.19 23.71 25.91 25.26 27.62 (% Faltas) 28.26 27.38 17.12 11.24 14.27 23.84 13.77 27.51 19.73 9.46 26.48 15.94 16.60 20.52 21.67 39.91 22.52 20.00 33.43 40.68 40.44 40.44 Os traços P1-p14 foram coletados usando VTrace sobre diversos meses de estações de trabalho com Windows NT que funcionavam como aplicações on-line. • ConCat é a contenação dos traços de P1-P14. • Merge(P) foi obtido fundindo os itens P1-P14. • O DS1 é um traço de sete dias feito com um exame de um usuário da base de dados. • SPC1 são varreduras seqüências longas. • S1-S3 leituras de disco originadas por um sistema de busca comercial. • Merge(S) foi obtido fundindo os itens S1-S3 4.2.14Clock-Pro Versão on-line do algoritmo adaptativo LIRS que, utilizando três ponteiros circulares e independentes sobre uma única fila LRU, procura distinguir 50 páginas com maior ou menor probabilidade de reutilização, classificadas respectivamente como “quentes” ou “frias” (“hot” ou “cold”). Esta classificação é baseada na reutilização recente de cada página e somente páginas “frias” são substituídas quando uma falta de página ocorre. De maneira similar aos algoritmos CAR e CART, o Clock-Pro mantém na fila algumas páginas recém-substituídas como referencial adicional temporário. (CASSETTARI e MIDORIKAWA apud JIANG et al.) 4.2.15CAR Versão on-line do algoritmo adaptativo ARC. Utiliza duas filas, complementares entre si, para armazenar os identificadores de cada página carregada na memória. Uma das filas engloba páginas residentes nas quais não se percebe uma tendência de reutilização pontual, enquanto a outra fila é dinamicamente preenchida por páginas que demonstram tal tendência. Ambas são controladas por ponteiros que se movimentam como no algoritmo Clock. A primeira fila tem prioridade na substituição, isto é, a probabilidade de uma página ser substituída na primeira fila é maior do que na segunda. Páginas substituídas permanecem nas filas por um certo tempo após deixarem fisicamente a memória, servindo como uma base histórica recente para a orientação do algoritmo. O tamanho das filas, gerenciado de modo dinâmico indica qual delas deve ter uma página removida em caso de falta de página. (CASSETTARI e MIDORIKAWA apud BANSAL e MODHA) 4.2.16CART Variação do algoritmo CAR que inclui um mecanismo adicional para diferenciar páginas referenciadas constantemente daquelas muito referenciadas em um único período. Utilizando um novo bit como filtro, o algoritmo classifica as páginas como sendo de “reutilização localizada” (“short-term utility”) ou de “reutilização constante” (“long-term utility”). Páginas do primeiro grupo têm prioridade de substituição quando se tornam inativas na memória. Tanto a lógica como a estrutura operacional do algoritmo CAR são mantidas, entretanto uma complexidade maior de 51 implementação é acrescentada.(CASSETTARI e MIDORIKAWA apud BANSAL e MODHA) 52 5 COMPARAÇÃO DOS ALGORITMOS Para demonstrar o funcionamento prático dos algoritmos de gerenciamento de memória, nas áreas: alocação e substituição de páginas, foram utilizados simuladores baseados em software. Inicialmente foi realizada uma busca na Internet a procura deste tipo de software. Foram obtidos resultados pouco satisfatórios quanto a os algoritmos de substituição de páginas, pois, grande parte dos simuladores suportava poucos tipos de algoritmos. Baseado na experiência acima, foi desenvolvido um simulador de algoritmos de gerenciamento de memória, surgiu assim o TSM (Talau Simulador de Memória). Este programa foi escrito em C ANSI, podendo assim ser suportado em diferentes plataformas de sistemas operacionais. Foi escolhida a linguagem de programação C devido a sua facilidade de interação com ponteiros de memória. O TSM atualmente na versão (http://geocities.yahoo.com.br/marcostalau/projetos/tsm) 0.0.5 suporta os seguintes algoritmos: FIFO, LRU, LFU, SC, CLOCK, OPT, NUR e WSCLOCK. O funcionamento do TSM está baseado em um arquivo com páginas, simbolizando um programa e através deste é gerado o processo durante a execução do simulador. O processo possui inúmeras páginas podendo ser uma seqüência com X números iguais ou diferentes. Quando o arquivo de processos está carregado, é a hora certa de executar este processo. O TSM possui uma memória com um tamanho definida pelo usuário, é nesta memória que as páginas do processo deverão ser executadas. No momento em que uma página não está na memória é gerada uma falta de página, também ocorre falta de página quando a memória está cheia e existem páginas que precisão ser carregadas. É neste 53 ponto que os algoritmos de substituição de páginas entram em cena. Estes algoritmos manipulam as páginas de memória com o objetivo de retirar uma delas da memória. Ao finalizar a execução do processo o TSM retorna a quantidade de faltas de páginas ocorridas e o tempo de execução total do programa. Se passada a opção “-g” como argumento de linha de comando, será obtido como resultado um arquivo com o histórico da execução do processo, pronto para ser executado pelo “gnuplot” (http://gnuplot.sf.net). 54 Figura 13: Tela de opções do simulador TSM. Figura 14: Simulador TSM sendo executado com o algoritmo LRU. Quadro 1: Trecho de código fonte do TSM. struct tabelaWSCLOCK { int pagina; int tempo; int bituso; int bitm; //modificação } *tabWSCLOCK; /* Abre arquivo com páginas e carrega em uma tabela. */ void carregaArquivo(char nome[], int *tabela) { 55 FILE *arq; int t = 0; int x = 0; int q = 0; char c; char numero[5]; arq = fopen(nome, "r"); if (arq == NULL) { fprintf(stderr, "ERRO ao abrir %s\n", nome); exit(-1); } while (!feof(arq)) { c = fgetc(arq); if (isspace(c)) { numero[x] = '\0'; x = 0; *(tabela + q) = atoi(numero); q++; continue; } numero[x] = c; x++; } *(tabela + q) = 0; } Para os algoritmos de alocação de memória foi encontrado na Internet um bom simulador o fits (http://www.utdallas.edu/~ivor/dl/fits/fits.html). O fits é um Applet Java, que é executado através de um navegador WEB. Surgiram dificuldades com este simulador no momento de receber os resultados no decorrer do da execução do applet para um arquivo, o simulador original não tinha este suporte, pois, applets tem sérias restrições de segurança não podendo acessar arquivos do disco de um computador local. Foi conseguido obter os fontes do fits e realizei algumas modificações nele para dar o suporte a criação de arquivo de registro dos dados. Para o applet poder ser executado com essa característica, adicionei um certificado digital nele, assim com a autorização do usuário através de uma caixa de dialogo do browser, pode-se realizar a escrita de arquivos no computador do usuário. Está versão alterada está disponível http://geocities.yahoo.com.br/marcostalau/codigos/java/simulador_fits. em 56 Para os algoritmos ARC, CAR e CLOCK-PRO foram encontrados artigos científicos premiados a respeito deles, nos quais pude extrair alguns dados interessantes. Os algoritmos NFU e MRU têm extrema semelhança com o LRU e LFU no nível de software. Por isso não foram testados. 5.1 Gráficos Os gráficos abaixo foram gerados pelo software “gnuplot”, este software foi escolhido por ser um software livre, ter ampla documentação, interação com linguagens de programação e fácil criação de gráficos com alta qualidade. 5.1.1 Simulador FITS Os dados inseridos no simulador para resultar os gráficos foram: • Mínimo tamanho segmento = 20 • Máximo tamanho segmento = 1000 • Tamanho da memória = 4000 57 Figura 15: Gráfico com algoritmos de alocação Analisando o gráfico pode-se constatar que o algoritmo de alocação de páginas BEST-FIT possui um menor número de faltas de páginas. 58 5.1.2 Simulador TSM Os dados inseridos para resultar neste gráfico foi um arquivo de processos com tamanho variado e um tamanho de memória de 10 páginas. 59 Figura 16: Gráfico com algoritmos de páginas com 50 páginas Figura 17: Gráfico com algoritmos de páginas com 100 páginas 60 Figura 18: Gráfico com algoritmos de páginas com 200 páginas Figura 17: Gráfico com algoritmos de páginas com 500 páginas 61 Figura 19: Gráfico com algoritmos de páginas com 1000 páginas Figura 20: Gráfico com algoritmos de páginas com 2000 páginas 62 Analisando os gráficos acima se pode concluir: • Como diz a teoria o algoritmo Ótimo (OPT) é o que sempre apresenta um menor número de faltas de páginas em todos os casos e deve ser usado para testes de comparação com algoritmos. • O LFU apresentou a segunda melhor pontuação nos gráficos acima. • Em terceiro lugar ficou o NUR. • E como já era esperado em último lugar ficou o FIFO e penúltimo lugar ficou o SC. 5.1.3 Outras pesquisas As imagens abaixo foram resultados de estudos por pesquisadores, publicados em artigos científicos. Figura 21: Gráfico do algoritmo ARC (MEGIDDO e MODHA, 03/2003) No gráfico acima P1 e P2 são dois processos diferentes em execução, pode-se concluir que o algoritmo ARC apresenta um número maior de faltas de páginas que o LRU. 63 Figura 22: Gráfico do algoritmo CAR (BANSAL e MODHA) No gráfico acima é feito uma comparação do algoritmo CAR com o CLOCK com base na falta de páginas. P1 e P2 são dois processos diferentes. No gráfico pode se constatar que o algoritmo car possui uma maior falta de páginas que o algoritmo clock. 64 Figura 23: Gráfico do algoritmo CLOCK-PRO (JIANG et al.) NO gráfico acima foi comparado a aplicação applu e blizzard com diversos tipos de algoritmos. O CLOCK-PRO obteve o segundo menor resultado em primeiro lugar ficou o OPT. 65 6 CONCLUSÃO O projeto de gerenciamento de memória é definido pelo hardware e pelo software. No hardware é definido como será feito o sistema de memória com tecnologias de circuitos, como por exemplo a memória virtual implementada em hardware. Com o software tem que ocorrer um controle dos recursos da memória do hardware pelo software, além de implementação de funcionalidades que não estão presentes no projeto de hardware. Portanto de nada adianta ter um melhor algoritmo de gerenciamento de memória, se o hardware não te ajudar no processo de funcionamento. Com os algoritmos de alocação de páginas foi concluído que o algoritmo BEST-FIT tem um número menor de faltas de páginas que os algoritmos FIRST-FIT e NEXT-FIT, porém esse número de diferença entre eles foi pequeno. Na implementação de um algoritmo de alocação de páginas em um sistema operacional a melhor opção é usar o algoritmo FIRST-FIT, pois, possui uma grande velocidade e tende a causar menos o problema da fragmentação. Na simulação de algoritmos por software o algoritmo Ótimo sempre terá um melhor desempenho. Por isso este algoritmo é aplicado com base para o teste de novos algoritmos. Qualquer algoritmo existente ou que possa surgir será no máximo igual aos resultados do Ótimo. O algoritmo FIFO e o seu primo SC apresentam um alto número de faltas de páginas, assim sendo eles são poucos usados no gerenciamento de memória. Com base nos estudos realizados foi constatado que o algoritmo LRU apresenta um melhor índice de falta de páginas implementável. Por isso ele é o algoritmo mais usado para a substituição de páginas em sistemas operacionais. Um bom exemplo disso é o uso dele no Linux. 66 6.1 Trabalhos Futuros Este trabalho oferece uma boa base de como um sistema de memória de computadores funciona, além de estudar os algoritmos de alocação e substituição de páginas. Com isto é possível implementar um componente de gerenciamento de memória em um kernel de um sistema operacional ou ainda realizar um estudo mais aprofundado dos algoritmos de memória. Figura 24: Arquitetura de um kernel 67 REFERÊNCIAS BIBLIOGRÁFICAS CASSETTARI, Hugo Henrique; MIDORIKAWA, Edson Toshimi. Algoritmo de Substituição de Páginas 3P: Acrescentando Adaptatividade ao Clock. XXV Congresso da Sociedade Brasileira da Computação. 22 a 29 de julho. CIC, Departamento de Ciência da Computação. Organização da Memória. Departamento de Ciência da Computação [CIC] Disponível em: <http://www.cic.unb.br/docentes/jacobi/ensino/OAC/Memoria.pdf > Acesso em 28 out. 2005. COTUCA, Colégio técnico de Campinas/Unicamp. Sistemas Operacionais. UNICAMP - COLÉGIO TÉCNICO DE CAMPINAS – COTUCA. Disponível em: <http://www.cotuca.unicamp.br> Acesso em 26 out. 2005. CHELLO, chello breedband internet - kabel en adsl, games, films en TV. pictures. Disponível em: <http://members.chello.nl/mlampers/Pictures2.htm> Acesso em 12 dez. 2005. DODONOV, Evgueni. Um Mecanismo Integrado de Cache e Prefetching para Sistemas de Entrada e Saída de Alto Desempenho. Dissertação (Mestrado em computação) – Universidade Federal de São Carlos. ETSI2, ETS Ingenieria Informática – Granada. ENIAC (Electronic Numerical Integrator and Computer). Disponível em: <http://www- etsi2.ugr.es/alumnos/mlii/eniac.htm> Acesso em 12 dez. 2005. JIANG, Song; CHEN, Feng; ZHANG, Xiaodong. CLOCK-Pro: An Effective Improvement of the CLOCK Replacement. MACHADO, Francis Berenger; MAIA, Luiz Paulo. Arquitetura de Sistemas Operacionais. 3ª ed. Rio de Janeiro: LTC, 2002. MEGIDDO, Nimrod; MODHA, Dharmendra S.. A Simple Adaptative Cache Algorithm Outperforms LRU. IBM Research Report. Feb. 2003. MEGIDDO, Nimrod; MODHA, Dharmendra S. ARC: A Self-Tuning, Low Overhead Replacement Cache. USENIX File & Storage Technologies Conference (FAST), March 31, 2003, San Francisco, CA. MEGIDDO, Nimrod; MODHA, Dharmendra S. one up on LRU. Ago. 2003. MEGIDDO, Nimrod; MODHA, Dharmendra S. Outperforming LRU with an Adaptative Replacement Cache Algorithm. 2004. MURDOCCA, Miler J.; HEURING, Vicent P.. Introdução à arquitetura de computadores. Rio de Janeiro: Campus, 2000. 68 MCCRAW, Terrance. Virtual Memory Page Replacement Algorithms. OLIVEIRA, Rômulo Silva; CARISSIMI, Alexandre da Silva; TOSCANI, Simão Sirineo. Sistemas Operacionais. 2ª ed. Porto Alegre: Sagra Luzzatto, 2001. SEDMAK, Stephen. Memory Management. 1997. SILBERSCHATZ, Abraham; GALVIN, Peter; GAGNE, Greg. Sistemas operacionais: conceitos e aplicações. Rio de Janeiro: Campus, 2000. SILBERSCHATZ, Abraham; GALVIN, Peter Baer; GAGNE, Greg. Operating system concepts. 6º ed. John Wiley & Sons, 2002. STALLINGS, Willian. Arquitetura e organização de computadores. 4ª ed. São Paulo: Prentice Hall, 2002. TANENBAUM, Andrew S.; WOODHULL, Albert S.. Sistemas Operacionais: projeto e implementação. 2ª ed. Porto Alegre: Bookman, 2000. TANENBAUM, Andrew S.. Sistemas operacionais modernos. 2º ed. São Paulo: Prentice Hall, 2003. URI, Universidade Regional e Integrada do Alto Uruguai e das Missões Gerencia da memória real. URI – Universidade Regional e Integrada do Alto Uruguai e das Missões. Disponível em: <http://www.uri.com.br/~chg/sisop1/memoria.pdf> Acesso em 27 out. 2005.