



































Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Os melhores documentos à venda: Trabalhos de alunos formados
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Comunidade
Peça ajuda à comunidade e tire suas dúvidas relacionadas ao estudo
Descubra as melhores universidades em seu país de acordo com os usuários da Docsity
Guias grátis
Baixe gratuitamente nossos guias de estudo, métodos para diminuir a ansiedade, dicas de TCC preparadas pelos professores da Docsity
Trabalho de AOC do curso Sistemas de Informação do CES/JF (Pipeline Arquitetura CISC X Arquitetura CISC)
Tipologia: Trabalhos
1 / 43
Esta página não é visível na pré-visualização
Não perca as partes importantes!
Bacharelado em Sistemas de Informação
Carlos Eduardo O. Velasco 1º Semestre / 2009
Bacharelado em Sistemas de Informação
A idéia do pipeline é bem simples. Imagine que você tenha de levar 4 sacas de roupa na lavanderia, lavar, secar e passar cada uma delas. Você chega à lavanderia às 18 horas e começa o trabalho da seguinte forma:
De acordo com o desenho, você leva 30 minutos lavando a roupa, 40 secando e 20 passando cada saco com uma certa quantidade de roupas. Se pararmos para analizar este tempo poderia ser otimizado. Da seguinte forma:
Agora, enquanto um saco está lavando você pode secar o anterior. E como a roupa não depende de que você fique ao lado da máquina, você pode passar a leva anterior e assim otimiza o tempo.
O pipeline funciona assim. Enquanto uma instrução passa para a próxima fase, podemos otimizar o tempo pegando a próxima a ser executada.
Seria ótimo se fosse apenas isto, mas não podemos esquecer que em programas de computador temos instruções condicionais e estas podem gerar erros no pipeline, se não tratadas de maneira correta.
Vamos explicar de maneira mais técnica agora...
O Pipeline é constituído por uma seqüência de estágios operando em paralelo. A saída de um estágio serve de entrada para o seguinte. Em um pipeline de cinco estágios, por exemplo, um
Bacharelado em Sistemas de Informação
· Pdr = Probabilidade de que, sendo a instrução um desvio, este efetivamente aconteça. · A eficiencia do pipeline é: Ef = 1/Tm = 1/(1 + D.Pd.Pdr).
Uma maneira de aumentar a eficiência do pipeline, consiste em utilizar uma predição da maneira em que o desvio será realizado, de modo a buscar a instrução que terá mais probabilidade de sucedê-lo.
Dois tipos de predições podem ser utilizadas: · Predição estática (em tempo de compilação): compilador coloca a instrução seguinte mais provável logo após o desvio. Exemplo: desvios em loops tem grande probabilidade de ocorrer; desvios devidos a chamadas de rotinas de exceção tem pequena probabilidade de ocorrer.
· Predição dinâmica (em tempo de execução): microprograma mantém tabela de endereços de destino de instruções de desvio e informações sobre o seu comportamento.
Os anos 60 deram origem ao início do desenvolvimento do primeiro supercomputador : o CDC 6600. Possuindo 1 CPU e 10 unidades de processamento periféricas, este computador tinha a possibilidade de realizar operações em paralelo. Considerado por muitos como a primeira máquina RISC, o 6600 era único também por outras razões: era uma arquitectura load/store (em que todas as operações ocorriam de registo para registo, excepto para leituras e escritas); possuia múltiplas unidades funcionais, temporização de instruções, e além disso foi das primeiras máquinas que usou uma nova técnica que lhe permitia processar mais que uma instrução de cada vez, e por essa razão não precisaria de esperar que uma instrução completasse para começar a próxima : o pipelining.
O pipelining é assim uma forma de obter uma alta performance ao "partir" o processamento de uma instrução numa série de estágios, que são ligados como as estações numa linha de montagem. Esta linha de montagem para processamento de instruções tem o nome de pipelining. À medida que as instruções fluem ao longo do pipeline, o hardware em cada estágio realiza algum processamento, até que as instruções, que deixam o pipeline são completamente processadas. A alta performance é obtida pelo paralelismo no processamento das várias instruções ao mesmo tempo, cada uma em diferentes estágios do pipeline.
É assim uma técnica fundamental de processamento que, sendo inicialmente introduzida nas arquitecturas RISC, estendeu-se às CISC, estando hoje presente, por exemplo, nos processadores Intel Pentium.
1.2.1 - Descrição Geral Assuma-se que se tem a seguinte sequência de instruções (sem objectivo evidente) para serem executadas...
load FP1 = mem(R1 + R2) # carrega o número em vírgula flutuante na posição de memória apontada por RB + RC no registo FP
load FP2 = mem(R3 + 4) # carrega o número em vírgula flutuante na posição de memória apontada por R3 + 4 no registo FP
Bacharelado em Sistemas de Informação
mult FP3 = FP1, FP2 # multiplicação em vírgula flutuante, em que o resultado é colocado em FP
store mem(R1 + R2) = FP3 # escreve o resultado ,contido em FP3, na posição de memória apontada por R1 + R2.
... e que cada uma delas demora 5 ciclos de relógio a ser executada.
É fácil de verificar que, o número de ciclos necessários para completar a execução destas 4 instruções seria de 4 * 5 ciclos = 20 ciclos.
Usando o conceito de pipelining, parta-se o processamento destas instruções, por exemplo, em 5 estágios, descritos da seguinte forma:
Assumindo que, em cada instante, cada um destes estágios está a realizar algum processamento, verifique-se que a sequência de instruções a serem executadas usando pipeline (os problemas com esta sequência de instruções será analizado mais tarde) será:
0 1 2 3 4 5 6 7
load FP1 = mem(R1 + R2) IF ID EX ME WB
load FP2 = mem(R3 + 4) IF ID EX ME WB
mult FP3 = FP1, FP2 IF ID EX ME WB
store mem(R1 + R2) = FP3 IF ID EX ME WB
Os 20 ciclos de relógio, dão assim lugar a apenas 7 ciclos!
Cada estágio do pipeline consiste em lógica e memória de alta velocidade, na forma de registos ou cache. Estes estágios estão separados por latches (um latch é um elemento de memória em que o valor de saída é igual ao valor do estado contido nesse elemento e esse estado é alterado sempre que os valores de entrada apropriados são alterados, em sincronização com o sinal de relógio).
Bacharelado em Sistemas de Informação
para atrasar a execução de uma instrução, quando se prevê uma paragem (ou dependência, ou stall).
Esses problemas podem ser classificados segundo os seguintes critérios:
O que significa cada um deles, e a(s) forma(s) de os resolver é dada de seguida. No final são descritas formas de prevenir paragens na pipeline, designadas por pipeline interlocks.
Mas antes de continuar convém fazer referência às situações excepcionais que podem causar um bloqueamento na execução normal do programa. As situações ditas de excepcionais são mais difíceis de manipular numa máquina pipelined pois a sobreposição de instruções torna mais difícil de saber quais aquelas que podem, com segurança, alterar o estado da máquina. Numa máquina pipelined, uma instrução é executada por partes e dessa forma não é completada antes de vários ciclos de relógio. Mas, infelizmente, outras instruções no pipeline podem causar excepções que poderão forçar a máquina a abortar a execução das instruções no pipeline que ainda não completaram a sua execução. Não é possível simplesmente analisar o Contador de Programa (PC) para saber qual foi a instrução que causou a excepção, e atribuir a excepção correcta à instrução correcta, e dessa forma algumas máquinas resolveram este problema relaxando simplesmente este requerimento, dando origem às chamadas de excepções imprecisas. Por exemplo, tendo o PC um determinado endereço no início do ciclo de relógio, e existindo uma excepção nesse ciclo, é atribuído o endereço da excepção ao valor do PC, mesmo que não tenha sido essa instrução a causar o problema, e deixar ao sistema operativo resolver o problema. No entanto, nos sistemas modernos esta não é uma solução viável, e a maioria deles usa modelos evoluídos de tratamento de excepções precisas.
1.2.2.1 - Riscos Estruturais e o Aumento dos Recursos Os riscos estruturais podem ocorrer quando duas instruções precisam, ao mesmo tempo, dos mesmos recursos para serem executados. Pode acontecer, por exemplo, quando se tem apenas uma memória (e apenas uma porta de acesso), ou então o caso de se ter uma operação que ocupe o estágio de execução por vários períodos de relógio (como a multiplicação seguinte).
A instrução imediatamente a seguir será retida, esperando pela liberação do estágio de execução.
Uma solução já referida, será de inserir "bolhas" ou "nops" para atrasar a execução da instrução. Assim...
Bacharelado em Sistemas de Informação
0 1 2 3 4 5 6 7
mult R1 = R2, R3 IF ID EX EX EX ME WB
store mem(R4) = R1 IF ID Nop Nop EX ME WB
... em que 'Nop' representa a "bolha".
Uma outra solução, a qual é usada por muitos sistemas de hoje, é aumentar os recursos existentes adicionando também mais lógica de controlo de modo a saber-se quais os recursos a serem usados em cada ciclo de relógio. Referindo-se aos exemplos anteriores, passaria por introduzir mais memória, ou utilizar mais unidades de execução, por exemplo, uma para processar a aritmética e outra para a escrita (mas se ocorressem duas instruções aritméticas seguidas voltaríamos ao mesmo).
1.2.2.2 - Riscos de Controlo e a Previsão de Salto Estes riscos, ou dependências, surgem da necessidade de tomar uma decisão baseada nos resultados de uma instrução que ainda não terminou. Acontecem, geralmente, em instruções de salto condicional, que podem alterar o fluxo das instruções ao longo do pipeline, pois o resultado destes saltos condicionais não são conhecidos até ao momento de serem executados. Uma instrução deve ser buscada em cada ciclo de relógio para sustentar o pipeline, mas a decisão acerca de realizar o salto ou não só é conhecida no final do estágio de execução. Dessa forma terão de ser inseridos Nops para obviar este problema.
0 1 2 3 4 5 6 7
branch Next, R1 >0 IF ID EX ME WB
Nop Nop Nop Nop Nop
Nop Nop Nop Nop Nop
Next: add R2 = R3, R1 IF ID EX ME WB
Como se pode verificar, é usado um salto condicional para a label "Next", baseado na comparação do registo R1 com 0. Assuma-se que o conteúdo de R1 é maior que 0. Enquanto que esta instrução é buscada, descodificada e executada, a unidade de busca de instruções tem de esperar que o resultado da comparação anterior seja conhecido. Neste pipeline, a comparação é feita no estágio EX, e a busca tem de esperar pelo ciclo seguinte para começar.
No exemplo anterior, foram introduzidos dois Nops para poder ser executada a adição. Este método é claramente ineficiente. Por essa razão, os desenhadores de sistema desenvolveram um outro processo para lidar com este problema, que consiste em prever qual será a decisão de tomar (ou não) o salto.
Bacharelado em Sistemas de Informação
1.2.2.3 - Riscos de Dados e o Forwarding Estas dependências ocorrem quando uma instrução depende dos resultados de uma instrução anterior que ainda se encontra no pipeline. Acontece, por exemplo, quando se tem uma operação que coloca o resultado num registo que é usado como operando na instrução seguinte. Uma solução óbvia será colocar nops de modo a atrasar a execução da instrução, como se exemplifica de seguida:
0 1 2 3 4 5 6 7 8
add R2 = R1, R0 IF ID EX ME WB
mult R0 = R2, R1 IF Nop Nop Nop ID EX ME WB
Mas além de óbvia, é também ineficiente! Uma outra forma de resolução deste problema consiste no uso de caminhos especiais, que transferem rapidamente os dados de um estágio para outro (depositando os valores em buffers especiais desenhados para este efeito), isto é, fazem o forwarding (ou bypassing) dos dados. Assim, as instruções seguintes não têm de esperar que essa chegue ao estágio WB, para depois lerem os operandos do ficheiro de registos.
Uma possibilidade de implementação será exemplificada na figura seguinte.
Na figura anterior foram adicionados 4 bypasses. Três vão para o estágio de execução, provindos dos estágio de execução, de acesso à memória e escrita de retorno, e um vai do estágio de acesso à memória para ele próprio. Obviamente representa apenas uma
Bacharelado em Sistemas de Informação
possibilidade de implementação, e existirão outras, mas verifique-se que o problema apresentado nas duas instruções anteriores (de adição e multiplicação) fica resolvido, pois o registo R2 ficará disponível na segunda instrução via o bypass que vem do estágio de execução para o estágio de descodificação.
Verifique-se que a sequência de instruções apresentadas no ponto 8.1. (Descrição Geral) apresenta o mesmo problema, e uma primeira solução será de inserir os nops, como se exemplifica de seguida.
0 1 2 3 4 5 6 7 8 9 10 11 12 13
load FP1 = mem(R1 + R2) IF ID EX ME WB
load FP2 = mem(R3 + 4) IF ID EX ME WB
mult FP3 = FP1, FP2 IF Nop Nop Nop ID EX ME WB
store mem(R1 + R2) = FP3 IF Nop Nop Nop ID EX ME WB
A instrução de multiplicação usa como operando um registo cujo valor só ficará disponível no final do estágio de acesso à memória da instrução de leitura anterior e a instrução de escrita usa um valor que só fica disponível no final do estágio de execução da instrução de multiplicação, logo não serão apenas precisos 7 ciclos de relógio para completar a execução desta sequência, como descrito atrás. Usando o forwarding (ou bypass) descrito anteriormente, é possível de retirar os nops entre a multiplicação e a instrução de escrita. O último nop entre a segunda instrução de leitura e a multiplicação não pode ser eliminado pois não existem bypasses que vão desde o estágio de acesso à memória para o estágio de descodificação (na implementação que foi exemplificada). O resultado final será assim:
0 1 2 3 4 5 6 7 8
load FP1 = mem(R1 + R2) IF ID EX ME WB
load FP2 = mem(R3 + 4) IF ID EX ME WB
mult FP3 = FP1, FP2 IF Nop ID EX ME WB
store mem(R1 + R2) = FP3 IF ID EX ME WB
1.2.2.4 - Pipeline Interlocks Como se verificou, uma dependência de dados, de controlo, ou de recursos pode causar que uma instrução seja bloqueada num estágio do pipeline à espera que a instrução anterior produza um resultado ou libere um recurso. Para ter a certeza que uma instrução é impedida de executar quando é necessário, isto é, quando poderá vir a causar uma paragem, o hardware verifica se existem dependências e bloqueia essas instruções de seguirem a sua
Bacharelado em Sistemas de Informação
Pipelines mais longos (Superpipelining) Para os pipelines discutidos até ao momento, o throughput máximo é de uma instrução por ciclo de relógio. Dado este constrangimento, um método óbvio de obter maior throughput será de aumentar a frequência de relógio. Uma forma de o fazer será de usar mais estágios, em que cada um deles realiza menos trabalho (e dessa forma demora menos a executar diminuindo também a período de relógio).
Enquanto que as instruções sejam independentes, pipelines mais longos dão origem a um throughput maior, na medida em que o relógio é também mais rápido. Mais estágios significa que mais instruções podem ser processadas em paralelo.
No entanto, com instruções dependentes, os melhoramentos na performance são limitados devido ao facto de os estágios de pipeline adicionais estarem preenchidos com nops ou bolhas, e não instruções. Essas bolhas ocorrem entre instruções em que uma delas requere que um certo resultado ou informação de controlo seja providenciado pela instrução anterior. Dividindo o trabalho em mais estágios simplesmente adicionará um maior número de bolhas, separando as instruções dependentes. À medida que o pipeline é tornado mais longo e o número de bolhas aumenta, é chegado um limite nos melhoramentos de performance pois os estágios adicionais não terão mais instruções, mas apenas bolhas.
Para cada estágio do pipeline, ocorre um certo atraso que decorre da escrita no registo pipeline (ou latch) que divide os estágios. Este atraso significa que o período de relógio não será reduzido em proporção directa com o número de estágios adicionados. Por exemplo, se uma implementação de 4 estágios com um período de relógio de 50 ns for dividida em 8 estágios, período de relógio provavelmente será algo superior aos 25 ns. Dessa forma, a performance poderá ser reduzida para pipelines mais longos quando as dependências de instruções limitam o número de instruções que podem ser processadas ao mesmo tempo, e a largura do pipeline adiciona uma maior latência.
Pipelines Paralelos Até agora, focou-se apenas "pipelines lineares" que possuem apenas um caminho que todas as instruções percorrem com o objectivo de serem processadas. Pipelines paralelos providenciam caminhos diferentes dependendo do tipo das instruções.
Bacharelado em Sistemas de Informação
Primeiro, existe um pipeline único para busca e descodificação de instruções, mas que depois se divide em partes paralelas dependendo do tipo da instrução a ser executada. Este tipo de pipeline permite que as instruções sejam executadas com maior independência. Uma instrução não é bloqueada apenas porque a sua precedente pode estar também bloqueada no pipeline ou a usar o estágio de execução por vários ciclos de relógio. Os pipelines paralelos podem ser de comprimentos diferentes, dependendo das suas funções. Por exemplo, um pipeline de multiplicação de número em vírgula flutuante será certamente maior que uma que realiza apenas operações lógicas simples. Por causa dessa variação de comprimento, instruções na pipeline podem completar numa ordem diferente daquela que foram iniciadas.
Uma vantagem importante destas pipelines ocorrem quando uma instrução é bloqueada na cache de dados devido a uma falha. Se a cache estiver num pipeline diferente das operações de vírgula flutuante, a instrução de vírgula flutuante indepente que se segue pode proceder e não é mantida atrás da instrução de memória que falhou a cache.
Processadores Superescalares Observou-se anteriormente que uma forma de melhorar o throughput do pipeline é tornar esse pipeline mais longo e aumentar a frequência do relógio. Uma outra forma é construir pipelines capazes de buscar, descodificar e executar simultaneamente mais de uma instrução de cada vez.
As implementações "superescalares" vão buscar o seu nome ao facto de "escalar" sugerir o processamento de um item de dados de cada vez (em contraste com o processamento vectorial usado em muitos supercomputadores). Processadores superescalares vão além do
Bacharelado em Sistemas de Informação
resolvida. Tipicamente, o pipeline é dividido em três grandes unidades: uma unidade de busca e despacho, unidades de execução e unidade de término.
A figura anterior mostra bem o modelo. A primeira unidade busca as instruções, descodifica- as, e envia-as para as correspondentes unidades funcionais, no estágio de execução. Cada unidade funcional possui buffers, chamados de Estações de Reserva, que guardam os operandos e a própria operação. Quando essa estação possuir todos os operandos e a unidade funcional está pronta a executar, o resultado é calculado. Nessa altura, depende da unidade de término de decidir se é seguro colocar esse resultado em registos (ou memória).
Este modelo básico possui assim, várias máquinas independentes a processar instruções: uma unidade a ir buscar e descodificar instruções, várias unidades funcionais a realizar operações e uma unidade que dá por terminada a execução das instruções. Para por os programas a comportarem-se como se estivessem numa máquina sem pipeline, a unidade de busca e descodificação despacha instruções na ordem que estão originalmente, e à unidade de término é requerido que escreva os resultados na ordem normal de execução do programa. Este modelo é designado por "término em ordem". Contudo as unidades funcionais, são livres de executarem as instruções na ordem que "quiserem". Um outro modelo de execução, consistirá em executar e terminar as instruções fora da ordem normal do programa designado por "término fora de ordem".
O pipelining dinâmico é geralmente combinado com a previsão de salto, dando origem ao conceito de "execução especulativa". Assim, "tendo em mãos" uma instrução de salto, o que o processador faz é dar uma previsão de salto, e a partir dessa previsão executar em paralelo as instruções seguintes. Caso se verifique uma previsão errada, terá de existir a possibilidade de descartar as instruções que foram executadas até então, e começar de novo a buscar e executar instruções a partir do salto. As máquinas dinâmicas são assim capazes de prever o fluxo de execução do programa, analisando as instruções para verificar qual delas
Bacharelado em Sistemas de Informação
será executada de seguida, e executá-las especulativamente baseado na previsão ou então nas dependências ocorridas com instruções anteriormente.
As motivações para a execução dinâmica são então as seguintes:
Executar especulativamente as instruções enquanto se espera que os problemas sejam resolvidos.
Optimizações por software Analisou-se anteriormente melhoramentos que eram possíveis ao nível do desenho do sistema, mas, dado que os programas que são desenvolvidos para esses sistemas passam sempre por um processo de compilação ou interpretação, cabe ao software, quer se trate do compilador ou interpretador, uma importante palavra acerca do assunto. São várias as técnicas de optimização de programas, e uma delas, largamente usada, é a de temporização de instruções. A temporização de instruções consiste apenas em resolver certas dependências executando entre essas intruções de risco, outras instruções que não trarão problemas. Assim, em vez de se inserirem bolhas, ou nops, o que o compilador faz é inserir instruções cuja ordem de execução não faz grande diferença. Assuma-se que se tem a seguinte sequência de instruções:
Entre a segunda instrução de leitura e a multiplicação, irá existir uma dependência de dados, que como se verificou anteriormente, terá de ser resolvida com uma bolha entre as duas, de modo a atrasar a execução da última. Mas se o compilador alterar a ordem das instruções para a forma:
Verifica que a dependência desaparece, pois substitui-se uma instrução que não fazia nada (apenas atrasava a execução) por outra que, atrasando também a execução da multiplicação, já realiza trabalho útil, e não cria problemas adicionais.
1.2.4 - Pipelining no PowerPC 604e O processador PowerPC 604e tem a possibilidade de obter um throughput de mais do que uma instrução por ciclo de relógio a partir dos vários desenvolvimentos em termos de performance que possui. Estes incluem várias unidades de execução que operam indepentemente e em paralelo, pipelining, despacho de instruções superescalar, previsão
Bacharelado em Sistemas de Informação
estágio de término, podem ser completadas 4 instruções por ciclo de relógio, em ordem normal de programa. No estágio de escrita de retorno, os resultados são escritos no ficheiro de registos. As instruções são buscadas e executadas concorrentemente, com a possibilidade de poderem ser executadas fora da ordem normal de programa. Os detalhes destas operações serão explicados nas secções posteriores.
Mas antes de analisar a estrutura do pipeline propriamente dito, convém dar uma vista de olhos às unidades, ou blocos, que compõem o processador PowerPC 604e, e que, dada a sua independência, relativamente umas às outras, irão permitir a execução paralela de instruções, isto é, o pipelining.
1.2.4.1 - As Unidades Funcionais do PowerPC 604e A figura dá uma representação (bastante mais esquemática e menos técnica que a figura anterior) da estrutura interna do processador 604e da Motorola.
Como se pode observar na figura, as unidades que se destacam são:
Bacharelado em Sistemas de Informação
Estas unidades garantem um fluxo correcto de instruções, e seus operandos, a serem executadas, bem como uma actualização correcta do estado da máquina.
1.2.4.1.1 - Unidade de Busca (Fetch Unit) Esta unidade providencia instruções á fila de instruções, acedendo à cache (L1) de instruções (corresponde a um modelo de Harvard como se pode observar). Tipicamente, realiza uma busca contínua e sequencial de, no máximo, 4 instruções de cada vez.
O endereço da próxima instrução a ser executada é determinado por várias condições, as quais obedecem às seguintes prioridades: