Prévia do material em texto
UNIVERSIDADE FEDERAL DE PELOTAS CENTRO DE DESENVOLVIMENTO TECNOLÓGICO PROGRAMA DE PÓS-GRADUAÇÃO EM COMPUTAÇÃO DISCIPLINA: ARQUITETURA DE COMPUTADORES PROFESSORES: MARCELO PORTO, LUCIANO AGOSTINI E BRUNO ZATT ALUNO: CARLOS ALEXANDRE SILVA DOS SANTOS DATA: 23/07/2020 RESUMO - TEMA 2: MIPS PIPELINE A ideia de pipeline vem das linhas de montagem proposta Henry Ford (1913), em que se reduziu drasticamente o custo de produção de automóveis onde o processo de montagem foi dividido em 29 etapas. Cada funcionário instalava apenas um componente antes de “empurrar” a peça para o colega seguinte. Uma peça que antes levava 20 minutos para ficar pronta passou a levar 13 minutos. No pipeline, portanto, é realizado um esforço para que todas as unidades operativas estejam sempre funcionando, e para que isto seja possível várias tarefas (instruções) estarão sendo executadas em paralelo. Para fins de exemplificação, a Figura 1 apresenta a ilustração da execução das tarefas típicas de uma lavanderia, realizadas sequencialmente e representadas pelas letras A, B, C e D, ao longo do tempo. Ao passo que a Figura 2 apresenta a execução destas mesmas tarefas, só que desta vez em pipeline. Figura 1 - Execução sequencial Figura 2 - Execução em pipeline Perceba que na Figura 1 são necessárias 8 horas para execução de todas as tarefas, com tempo entre duas mudas de roupas prontas de 2 horas. Em contrapartida, na Figura 2, são necessárias apenas 3,5 horas para execução de todas as tarefas, com tempo entre duas mudas de roupas prontas de ½ hora. Com o surgimento das arquiteturas do tipo RISC (Reduced Instruction Set Computer), foi possível o uso de pipeline nos processadores, que é um dos motivos pelos para o elevado desempenho destes. Convém destacar que registradores de pipeline não são visíveis para programadores, uma vez que são usados na organização e não na arquitetura. A cada novo ciclo, as unidades operativas recebem um novo conjunto de dados dos registradores de pipeline de entrada, e salvam os resultados nos registradores de pipeline de saída. Enquanto que no Monociclo o ciclo tinha que ser grande suficiente para dar conta da instrução mais lenta, no caso a instrução Load. Agora no pipeline o ciclo tem que ser grande suficiente para dar conta da etapa mais lenta, que é a memória. Particularmente, no caso do MIPS, com cinco etapas, por exemplo, cada instrução seria executada simultaneamente, porém em estágios diferentes. Com isso, tem-se a “impressão” que a cada novo ciclo está sendo gerada uma instrução nova, caso todos os problemas de adiantamento tenham sido resolvidos. Quanto à organização do MIPS pipeline, este possui um bloco operativo em pipeline (Pipeline Datapath), separado em cinco partes, cada uma correspondendo a um estágio de execução de uma instrução, conforme apresentado na Tabela 1: 1 BI Busca de instrução. 2 DI Decodificação da instrução. e leitura do banco de registradores 3 EX Execução ou cálculo de endereço. 4 MEM Acesso à memória de dados. 5 ER Escrita no banco de registradores. Até cinco instruções podem estar em execução durante um dado ciclo de clock. A Figura 3 apresenta a ilustração do Bloco Operativo em Pipeline. Uma forma de apresentar a execução em pipeline é imaginar que cada instrução executa em seu próprio bloco operativo. Estes blocos operativos são deslocados uns em relação aos outros, a fim de mostrar a relação entre as instruções. Se tu tudo ocorrer bem no pipeline, ou seja se os conflitos forem resolvidos, uma nova instrução é entregue a cada ciclo, dá a impressão que é executada uma instrução por ciclo. Porém, agora o ciclo de relógio é menor em relação ao Monociclo. Todavia, se o MIPS pipeline ainda se está “entregando” uma instrução por ciclo (mesmo que o ciclo de relógio seja menor), faz com que este tenha um desempenho maior que o Monociclo, caso todos os problemas de conflito, inerentes do pipeline, sejam devidamente resolvidos. Entretanto, há inconvenientes no MIPS pipeline, e um deles, por exemplo, é que a execução de uma única instrução será um pouco mais lenta que no MIPS Monociclo, devido a todas as etapas terem o mesmo tempo. Se a ULA (Unidade Lógico Aritmética) era mais rápida que a memória no MIPS Monociclo, agora, no MIPS pipeline, a ULA tem que trabalhar no mesmo tempo da memória, de forma que seja garantido um sincronismo do ciclo de clock. O pipeline tem no geral, conceitualmente, nunca vai chegar a taxa de uma instrução por ciclo, por que se tem dois custos adicionais. Um é o problema do preenchimento da primeira instrução, pois a primeira instrução vai gastar os cinco ciclos. Este problema é causado, portanto, porque existe um overhead referente ao preenchimento do pipeline. Outra é a questão do balanceamento, pois a ULA tem que gastar o mesmo tempo da memória, pois precisam gastar o mesmo tempo. Se o pipeline não estiver balanceado gastar-se-á mais tempo para resolver esta situação. Neste sentido, o MIPS pipeline possivelmente nunca operará no máximo de sua capacidade. Agora, quanto maior for o programa que se está executando, e se todos os conflitos forem resolvidos, maior será a probabilidade de se utilizar chegar ao ganho teórico máximo do pipeline. O pipeline, em termos de custos de hardware e consumo de energia adicional, são necessários acrescentar os registradores para fazer pipeline, que são pequenos. No entanto, o aumento dos custos supracitados trazem um desempenho maior em relação ao Monociclo. Basicamente, o hardware utilizado no Monociclo também é utilizado no pipeline, inclusive a Unidade de Controle (UC), bastando se colocar as conexões corretas nos registradores de pipeline, de forma que o sincronismo funcione corretamente. Existem situações de execução no pipeline em que a instrução seguinte não pode ser executada no próximo ciclo de relógio. Este tipo de situações são chamadas de conflitos. Em termos de problemas que o pipeline traz são três tipos de conflitos: Os Estruturais (Structural Hazards), que quando duas instruções diferentes querem usar ao mesmo tempo uma unidade operativa, e esta unidade operativa só está disponível para uma instrução por vez. Para isto, esta unidade operativa deve ser replicada, como no caso do Somador apresentado no Monociclo. Os Conflitos de Controle (Control Hazards), que são causados por instruções de desvio: condicional e não condicional. Quando se lê a instrução da memória ainda não se sabe se é uma instrução de desvio, portanto não se sabe o que fazer. No próximo ciclo em que se verifica que trata-se de uma instrução de desvio condicional, no estágio 2, já foi lida a próxima instrução. Se for um Jump ou Beq já foi lida a instrução, e talvez esta não necessite ser executada. Basicamente, se utiliza predição estática para resolver este problema, nos processadores mais antigos, e nos processadores mais atuais se utiliza predição dinâmica, em que se tem um coprocessador que fica “observando” o processador sendo executado.Este coprocessador, por sua vez, irá controlar o histórico das ocorrências dos “saltos”, de forma que seja possível tomar uma decisão mais acertada. Exemplo: A cada cinco vezes que se passar pela instrução pula-se, mas nas outras quatro instruções, não pula. Isto só é possível do ponto de vista abstrato, em que não se apresenta nenhuma solução prática e detalhada disto. E, por fim, o Conflito de Dados (Data Hazards), que é o mais crítico de todos, devido a sua reincidência. Este tipo de problema, quando não resolvido, torna a solução do MIPS pipeline pior que a solução Monociclo. No MIPS há dois tipos de conflito, Tipo 1 e Tipo 2. O Tipo 1 é quando o dado que está na saída do registrador de saída da ULA precisa ser usado na entrada da ULA, enquanto que no conflito Tipo 2 o registrador de saída do estágio de memória precisa ser usado na entrada da ULA. Convém destacar que não existe um conflito Tipo 3, pois no mesmo ciclo que em que se escreve no banco de registradores precisa-se ler este dado, o que pode ser realizado, uma vez que na primeira na primeira metade do ciclo se faz a escrita no banco de registradores e na segunda é realiza a leitura, o que se possibilita já ter o dado correto. A solução deste tipo de problema é resolvido por hardware. Não é interessante se deixar para os compiladores resolver este tipo de problema. A técnica para resolver este caso chama-se adiantamento. Esta técnica, basicamente, “usa” o dado da saída da ULA ou da saída da memória antes dele ser escrito no banco de registradores, e, dessa forma, com um grau maior de complexidade no Controle tomar a decisão correta, e, consequentemente, evitar todos os conflitos de dados causados por instruções do tipo R, que estão utilizando a ULA por algum motivo, e quando se está com a instrução Load só se consegue resolver conflitos Tipo 2, não conseguindo se resolver apenas conflitos Tipo 1, em que não há como se resolver, deixando para o compilador esta tarefa. De qualquer forma, o hardware terá que resolver quando vem um código do compilador que tem um conflito Tipo 1 causado por um Load. Neste caso, deve-se transformar um conflito Tipo 1 em Tipo 2, de forma que se possa resolver o problema empregando-se a técnica de adiantamento (forwarding ou bypass). A Figura 4 apresenta a ilustração do bloco operativo em Pipeline com Sinais de Controle: O pipeline é uma solução clássica utilizada em circuitos digitais para soluções de projetos de hardware. A ideia vai na linha de que se tem uma ULA com grande capacidade de processamento, o desafio é “usá-la” a maior parte do tempo possível. Neste sentido, são acrescentados elementos de hardware no entorno da ULA, com o propósito que esta funcione a maior parte do tempo possível. Para tarefas que exijam alto desempenho o MIPS pipeline pode ser uma solução mais adequada, ao passo que para aplicações em que alto desempenho não seja uma prioridade, o MIPS Monociclo poderá ser uma boa solução.