Powered By Blogger

quinta-feira, 10 de fevereiro de 2011

Especificações e características dos processadores

Há alguns termos já referidos, e outros que aparecerão mais adiante, que poderão causar alguma confusão a quem não está familiarizado com eles. Vamos tentar vero significado de alguns desses termos e especificações referentes aos processadores, isto é, termos como barramentos, registos, velocidade e outros.

Barramentos:
Uma das características principais de um processador ou CPU são os seus barramentos. Os barramentos são “auto-estradas” por onde circula a informação, seja no interior do CPU ou do interior para o exterior, e vice-versa. Os barramentos internos transportam a informação entre os vários componentes internos do processador, isto é, coprocessador aritmético, cache L1, registos, etc. Quanto aos barramentos externos, já há muito mais a dizer.
Os barramentos externos são três: barramento de dados, barramento de endereços e barramento de controlo, cada qual com a sua função específica. Vamos agora analisar cada um deles, começando pelo barramento de endereços.


Barramento de endereços:

O barramento de endereços permite identificar qual o componente e a localização exacta dentro do mesmo, para que o processador possa comunicar com ele e enviar os respectivos dados. No entanto, o dispositivo de destino tem de saber que algo lhe é dirigido e para isso usa um descodificador próprio, o “adress decoder”, que lhe permite identificar o endereço e saber qual a localização no seu interior.

Como vimos, o barramento de endereços transporta a informação usada para descrever a localização de memória para a qual os dados serão enviados ou de onde os dados serão recolhidos. Cada fio de barramento de endereços transporta um único bit de informação que corresponde a um só dígito do endereço. Quantos mais fios ou dígitos o processador tiver para calcular estes endereços, maior será o número total de localizações endereçáveis. O tamanho, ou o comprimento do barramento de endereços, indica a quantidade máxima de memória que o processador poderá endereçar, pelo que vamos ver como é que isso funciona.

Como já sabemos, os computadores usam um sistema numérico binário ou de base 2. Assim, um número com dois dígitos permite-nos obter quatro endereços (00,01,10 e 11), calculados do seguinte modo: 2 elevado à potência 2; um número com três dígitos já nos permite oito endereços (000 a 111), que é o mesmo que dizer 2 elevado à 3ª potência.

Por exemplo, um processador Intel 8088/86 tem um barramento de endereços de 20 bits, pelo que teremos 220, o que nos dá 1.048.576 bytes ou 1 MB de endereços de memória.


Barramento de dados:

O barramento mais frequente discutido é o dos dados. Neste barramento, tal como o nome indica, circulam os dados que são recebidos ou enviados, de e para periféricos e memória. Quantos mais sinais puderem ser enviados simultaneamente, maior quantidade de dados pode ser transmitida durante um determinado intervalo de tempo. Assim, e em consequência disso, teremos um barramento mais rápido.

Nos computadores, os dados circulam como informação digital, a qual consiste no intervalo de tempo que um fio condutor leva para transportar um só bit, seja ele de valor “1” ou “0”. Isso quer dizer que, quantos mais fios tiverem, maior será o número de bits individuais que o microprocessador consegue transportar durante o mesmo intervalo de tempo. Assim sendo, um processador de 16 bits tem 16 fios a transmitir e a receber dados, pelo que terá um barramento de dados de 16 bits. Um microprocessador de 32 bits tem o dobro dos fios e assim consegue transmitir o dobro dos dados simultaneamente, durante o mesmo intervalo de tempo que o seu congénere de 16 bits.

Para percebermos isto melhor, vamos utilizar um exemplo que não será do dia-a-dia, mas pelo menos é do fim-de-semana. Imaginemos um estádio de futebol em dia de jogo, onde temos 16 portas que nos permitem fazer entrar 16 adeptos simultaneamente. Se demorar 20 segundos para que cada conjunto entre no estádio, em 1 minuto conseguimos introduzir 48 adeptos. Mas se tivermos 32 portas em vez de 16, conseguimos no mesmo intervalo de tempo fazer entrar o dobro dos adeptos.

Vejamos o significado de cada uma destas características:
  • Frequência externa – É a velocidade com que o processador comunica com os componentes externos, por outras palavras, a velocidade dos barramentos externos.
  • Frequência interna – Em oposição à anterior, trata-se da velocidade dos barramentos internos ou, como é mais conhecida, velocidade de processamento.
  • Registos internos – Indica o maior número que o processador pode manipular numa só operação.
  • Barramento de dados – Transporta os dados de e para o exterior do processador.
  • Pipelines – Indica quantos processos o processador consegue executar simultaneamente.
  • Memória – Capacidade máxima de memória endereçável pelo processador. Depende do tamanho do barramento de endereços.
  • FPU – Floating Point Unit ou coprocessador matemático, como é mais conhecido.
  • Cache L1 – Cache nível 1 ou cache interna.
  • MMX- Capacidade de executar operações multimédia.
Algumas destas noções já foram referidas, as outras serão vista mais à frente.


Barramento de Controlo:

O barramento de controlo tem como função primordial a sincronização do processador, provocam estados de espera que necessitam de ser controlados, de modo que a comunicação entre o processador e os componentes externos seja feita eficazmente.


Registos Internos:

No tamanho dos registos internos temos um bom indicador da quantidade de informação que o processador pode operar num determinado tempo.

Os processadores podem manipular números de qualquer tamanho, mas quanto maior for o número, mais tempo o processador demora a executar as operações necessárias.

Os registos são áreas de armazenamento internas do processador e são usadas para guardar dados que estão por ele a ser “trabalhados”. Os registos são o mais rápido tipo de memória acessível ao processador, isto porque, além de fazerem parte integrante do processador, também estão ligados directamente á sua lógica.

A maior parte das operações é executada nos registos: o processador não pode executar operações aritméticas directamente na memória, por isso, se quisermos adicionar o valor 1 a uma localização de memória, o que o processador faz é carregar o valor inicial da memória para um registo, adicionar 1 ao registo e depois guardar o valor novamente na memória. Podemos analisar um exemplo disso nas páginas referentes ao funcionamento do microprocessador.

Alguns processadores têm um barramento de dados interno de tamanho diferente do barramento de dados externo. Um bom exemplo disso é o 8088 e o 386SX, cada um deles com um barramento de dados interno que é o dobro do correspondente barramento externo. Estes desenhos híbridos são versões mais económicas do processador original. O 386SX, por exemplo, pode transportar dados internamente com um tamanho de registos de 32 bits, mas, para comunicar com o exterior, o chip está limitado a um barramento de dados de 16 bits.

Os registos internos, por vezes, são maiores do que o barramento de dados, o que quer dizer que o processador necessita de dois ciclos de relógio para encher um registo antes de ele poder ser usado. Podemos ver como exemplo disso o 386SX e o 386DX, ambos com registos internos de 32 bits, embora o 386SX necessite de dois ciclos para encher os registos, enquanto que o 386DX necessita somente de um. O mesmo acontece quando os dados são passados dos registos internos de volta ao barramento do sistema.

No entanto, no Pentium temos o caso inverso. O Pentium tem um barramento de dados de 64 bits, mas somente 32 bits nos registos internos. Isto pode parecer problemático para o funcionamento do processador de informação. É quase como se o Pentium tivesse dois processadores de 32 bits num só chip. Além disso, o barramento de dados de 64 bits assegura um funcionamento eficiente desses registos de 32 bits.


Unidade de Interface de Barramentos:

É a parte do processador que faz a interface, ou ligação, entre ele e o resto do sistema. O seu nome vem de facto de lidar com a informação que se movimenta através do barramento de dados, a ligação primária para a transferência de informação de e para o processador. Ela é responsável por responder a todos os sinais que vão para o processador e gerar sinais que saem do processador e gerar sinais que saem do processador para o resto do sistema.


Unidade de Controlo:

A unidade de controlo é o circuito que controla o fluxo de informação no processador e coordena as actividades das restantes internas.

As funções executadas pela unidade de controlo variam gradualmente de acordo com a arquitectura do CPU, isto é, num processador que execute instruções x86 nativas, a unidade de controlo executa, entre outras, as tarefas de descodificação, gestão de execução e armazenamento de resultados. Num processador de arquitectura RISC, a unidade de controlo tem um trabalho significativamente mais activo. Ela gere a “tradução” de instruções x86 para micro-instruções RISC, gere os tempos de execução das micro-instruções entre as várias unidades de execução e controla o output dessas unidades de modo a que acabem no momento em que é suposto isso acontecer.


Coprocessador Matemático:

O coprocessador matemático, ou, mais correctamente, unidade de vírgula flutuante ou FPU (Floating Point Unit), é dedicado à execução de funções ou operações matemáticas com números de vírgula flutuante. Um número de vírgula flutuante é aquele que não é inteiro. Os números inteiros e os dados representados por números inteiros são processados por um outro componente do processador, a Unidade Aritmética e Lógica.

Desde o 486DX que o coprocessador matemático passou a ser uma parte integrante do processador, excepção feita ao 486SX. Nos processadores anteriores ao 486, as operações de vírgula flutuante eram executadas pela unidade aritmética e lógica, excepto nos casos em que o PC possuía um coprocessador matemático externo para a execução dessas operações. O coprocessador trabalhava também com o processador para aumentar a performance de aplicações com cálculo matemático intensivo.


Unidade Aritmética e Lógica:

No PC, grande parte do trabalho é feito com informação inteira, isto é, números inteiros e dados que são representados por números inteiros. Nos números incluímos números, caracteres e dados similares. Os números que não são inteiros são números de vírgula flutuante.

É na unidade aritmética e lógica que as instruções são executadas e o trabalho é feito. Nos processadores mais antigos, só existe uma destas unidades, onde as instruções são processadas sequencialmente. Nos processadores mais recentes, já temos unidades, permitindo que mais uma instrução seja executada simultaneamente.


Velocidade do Processador:

A velocidade do relógio de sistema de um computador é medida como frequência ou número de ciclos por segundo. Um oscilador de quartzo controla a velocidade de relógio. Quando uma tensão é aplicada ao quartzo, ele vibra a uma determinada frequência. A oscilação emana do cristal na forma de corrente alterna na proporção da harmónica do cristal – esta corrente alterna é o sinal do relógio.

Um computador trabalha a milhões destes ciclos por segundo, pelo que a sua velocidade é medida em megahertz (MHz), isto tenso em linha de conta que um hertz é igual a um ciclo por segundo.

A denominação Hertz foi dada em homenagem ao físico alemão Heinrich Rudolph Hertz. Em 1885, ele provou através da experimentação, a teoria electromagnética, que diz que a luz é uma forma de radiação electromagnética e propaga-se através de ondas.

Quando vemos num processador 600 MHz, sabemos que a frequência do relógio é de 600 MHz, pelo que temos na placa principal um pequeno oscilador de quartzo que oscila continuadamente a um determinado número de impulsos por segundo. A cada impulso algo acontece no processador. Assim, quantos mais impulsos por segundo, maior número de dados são processados por segundo.

Os primeiros processadores trabalhavam a 4,77 MHz e, subsequentemente, foram aumentando para 8 MHz, 16 MHz, 25 MHz, 66 MHz, 90 MHz, 133 MHz e 200 MHz, até às velocidades que hoje conhecemos e que se aproximam cada vez mais dos 200MHz.

Para atingir estes valores de velocidade de processamento, os fabricantes tiveram de utilizar uma técnica de multiplicação de frequência, a qual vamos ver seguidamente.

O grande problema das altas frequências de relógio é conseguirmos assegurar que todos os outros componentes electrónicos trabalhem de acordo com o processador. É relativamente simples fazer com que os dados se movam a grandes velocidades dentro do integrado do CPU. Mas quando essa operação se passa cá para fora, isto é, nos circuitos de apoio, aí pode não correr tão bem. Os outros componentes têm de ser capazes de dar resposta às exigências de velocidade do processador. Quando a frequência atinge valores muito elevados, as pistas do circuito impresso começam a actuar como antenas de radiofrequência, dando-se o aparecimento de várias formas de ruído. Resumindo, torna-se extremamente caro e difícil construir todo o hardware de modo a trabalhar à mesma velocidade do processador.

A solução para o problema é dividir a frequência do relógio por dois:
  • Uma frequência interna, alta que controla o funcionamento do CPU.
  • Uma frequência externa, baixa, que controla o barramento do sistema. É aqui que o CPU troca os dados com os dispositivos de I/O.
O primeiro processador a utilizar esta técnica foi o 486DX2 25/50 MHz da Intel, o que proporcionou a possibilidade de se adquirir por um baixo preço um processador que nos dava 90% da performance do 486DX 50. O DX50 trabalhava a 50 MHz, tanto internamente como externamente. O DX2 trabalhava a 25 MHz externamente, isto é, no barramento de sistema. Isto permitiu a construção de placas debaixo custo e a utilização de memória RAM também mais barata.

Esta duplicação da velocidade do relógio ocorre no interior do processador. Se o cristal da placa principal oscilar a 25 MHz, o processador receberá um impulso a cada 40 nanossegundos. No interior do processador esta frequência é dobrada para 50MHz. Agora, no interior do processador, o relógio dá um impulso a cada 20 nanossegundos. Esta frequência controla todas as transacções internas., incluindo, entre outras, a unidade de vírgula flutuante, a unidade aritmética e lógica e os registos internos. A única área que continua a funcionar a 25 MHz é a das transferências externas de dados, ou seja, a comunicação coma RAM, a Bios e os I/O.

O problema da velocidade também é crucial para a memória RAM. As SIMM FPM ou EDO trabalham a 66MHz; quanto muito poderão chegar aos 75MHz, porque os processadores Pentium necessitam de factores multiplicativos internos que vão de 2 até 5.

Com a introdução , em 1998, da RAM PC100 a trabalhar a 100MHz, juntamente com novos chipsets e placas principais, passou-se a usar factores de 3.5,4 e 4.5, o que permitiu ter CPU a 350MHz e 450MHz. Mas com os Pentium II, Celeron e Pentium III passamos a operar com factores superiores a 12, o que, associado à RAM PC133, nos permitem atingir os 1700 MHz.


Overclocking:

Já que estamos a falar de velocidade do processador, vamos dizer algumas palavras acerca do overlocking.

Dado que quase todas as placas principais nos permitem alterar livremente a velocidade do barramento e a velocidade do relógio, em princípio, podemos aumentar a velocidade de processamento da nossa máquina, isto é, podemos configurar a nossa placa de modo que o nosso computador funcione, por exemplo, a 800 MHz, mesmo que as características de fábrica digam que ele é um 600 MHz, isto é, se ele funcionar, o que nem sempre acontece.

As frequências que podemos alterar são:
  • A velocidade de barramento, normalmente de 100MHz ou 133 MHz, mas digamos que a queremos alterar de 100 MHz para 133 MHz.
  • A velocidade do processador pode também ser aumentada e aqui esse aumento pode ser efectuado de dois modos: pelo aumento da velocidade do barramento e pelo aumento do seu factor multiplicativo.
O resultado de qualquer um destes processos é um processador mais rápido. No entanto, se aumentarmos a velocidade do barramento, isso vai afectar também a velocidade com que os dados são enviados e recebidos da RAM e para isso a RAM também tem de suportar esse aumento.

Por outro lado, quando aumentamos a velocidade interna do processador, temos de ver se as aplicações que utilizamos funcionam eficazmente, pois as muitas aplicações não suportam esse tipo de aventuras.

Quando fazemos o overlocking, temos de ter em atenção um factor extremamente importante nos processadores: aquecimento, já que o aumento da temperatura é um dos maiores perigos para o nosso processador.

Quanto mais aumentarmos a velocidade de processamento, maior necessidade temos de uma boa refrigeração para o processador. Os processadores são construídos com tecnologia CMOS, a qual funciona melhor a baixas temperaturas. Assim, com o aumento da temperatura, podemos ter o resultado oposto ao desejado, isto é, uma drástica diminuição da performance.

Por isso, se está a pensar fazer o overlocking à sua máquina, primeiro veja se o processador o permite, procure saber qual a performance máxima que poderia tirar dele e, muito importante, não se esqueça de reforçar o dissipador de calor do processador. Tente documentar-se o melhor possível acerca do assunto e a Internet é uma óptima fonte de informação.


Cache Interna:

A cache interna apareceu pela primeira vez no processador Intel 80486DX e denominou-se L1 (Level 1). Desde esse momento, a cache teve o seu desenvolvimento natural, principalmente em tamanho.

Nesta tabela podemos ver que alguns processadores têm também uma cache L2, o equivalente À cache externa situada nas placas principais, que posteriormente começou a ser parte integrante do processador, mas vamos abordar este assunto posteriormente.
Vejamos agora qual a sua função e com funciona.

O processador tem de receber e entregar os dados a alta velocidade. A memória RAM não consegue acompanhar essa necessidade de velocidade, pelo que foi criada uma memória RAM especial, a que se chamou cache, a qual é utilizada como área de armazenamento temporário. Para se tirar a máxima performance do CPU, o número de transacções para o exterior deve ser minimizado. Quanto mais dados puderem ser mantidos dentro do CPU, melhor será a performance. Tomemos como exemplo os processadores 486, equipados com uma unidade de vírgula flutuante e uma cache interna de 8 KB. Estes dois elementos ajudam a minimizar o fluxo de dados que entra e sai do CPU, aumentando a sua performance.

Como já vimos, a cache funciona como armazenamento temporário para instruções frequentemente utilizadas, reduzindo assim a busca de dados na memória principal do sistema.

Apesar da cache L1 aparecer inicialmente no 486, a partir do Pentium ela passou a ter um refinamento. O 486 tem uma cache unificada de 8KB, que era usada para o código e para instruções. A partir do Pentium, os processadores passaram a ter a cache L1 dividida em duas partes, sendo uma delas reservada para dados e outra reservada para código. Retomando o exemplo do Pentium, temos uma cache L1 com 16 KB, sendo 8 KB para código e 8 KB para dados. Vejamos as características de cada um destes tipos de cache.

Temos as seguintes características da cache única:

  • Para um dado tamanho de cache, uma cache única apresenta uma taxa de acerto maior do que caches separadas.
  • Apenas é necessário projectar uma cache.
  • A manipulação do código é mais simples.

Vejamos agora as caches separadas:

  • Reduzem os conflitos de barramento.
  • Aumentam a disponibilidade da cache quando necessário.

A opção do uso de caches separadas para o Pentium foi devida à necessidade de uma maior largura debanda do que a que era proporcionada pela cache única.

A memória cache torna-se especialmente importante nos processadores em que a frequência interna é multiplicada, o que a torna muito superior à externa. Assim, a cache permite uma recepção e entrega de dados muito mais rápida.

Como já foi referido e podemos ver na figura 3.19, os computadores têm dois níveis de memória cache, a L1 interna e a L2 externa, mas que posteriormente passou também a ser colocada no próprio chip do processador, com notórias vantagens a nível de performance global, como veremos mais à frente.


Arquitectura Superescalar:

O termo superescalar refere-se a uma arquitectura de processador que tenha mais de uma unidade de execução ou pipelines. Estas unidades são nada mais nada menos que os locais do processador onde são processados os dados e as instruções.

No caso de uma arquitectura simples, as instruções são executadas numa só pipeline, enquanto que numa arquitectura superescalar as instruções são executadas em duas ou mais pipelines.

Vamos ver com um pequeno exemplo como isso se processa, tomando o caso dos processadores i486 e Pentium, sendo o primeiro um processador convencional e o segundo um superescalar de grau dois, isto é, capaz de executar duas instruções simultaneamente.
Imaginemos um programa com duas instruções seguidas: A+B e C+D. Como as instruções não têm qualquer dependência entre elas, C+D antes de A+B não tem qualquer interferência no resultado final. Assim sendo, o processador pode executá-las simultaneamente, isto é, podem ser executadas paralelamente, uma em cada canal ou pipeline. Com isto podemos obter o dobro do desempenho em relação a outros processadores anteriores ao Pentium, já que foi o primeiro superescalar da Intel.

No entanto, se o nosso programa tiver instruções dependentes, isto é, a continuação de uma dependa do resultado da outra, a operação já se processa de outro modo.

Se tivermos a instrução A+B e (A+B)+C, podemos ver que esta segunda instrução não pode ser executada sem que a primeira forneça um resultado, pelo que cada instrução será executada pela sua ordem lógica, coo aconteceria em qualquer processador convencional anterior ao Pentium (fig. 3.22).

Fig. 3.22 – Tipos de pipelines


Comparativamente com a execução simples, ou sequencial, o pipelining leva-nos a um aumento da performance do processador. Teoricamente, quantos mais estágios tivermos numa pipeline, maior será a velocidade que podemos tirar dela. Por exemplo, supúnhamos que são necessários 12 ciclos de relógio para processar todos os passos necessários de uma instrução; se usarmos uma pipeline de quatro estágios, o máximo que ela consegue processar será uma instrução por cada três ciclos, mas se usarmos uma pipeline de seis estágios, já conseguimos uma instrução em cada dois ciclos. Como élógico, isto é somente um exemplo muito simplificado.


Processadores RISC e Processadores CISC:

Os processadores obedecem a uma de duas tecnologias, a RISC (Reduced Instruction Set Computer) e a CISC (Complex Instruction Set Computer). Até ao aparecimento do Pentium Pro, todos os processadores, para PC é claro, eram baseados na tecnologia CISC. Esta classe de processadores possui u grande conjunto de instruções em código máquina. Essas instruções necessitam de ser descodificadas de modo a poderem ser executadas. Para isso, os processadores CISC socorrem-se de um microcódigo interno que indica ao processador como deve manipular cada instrução individualmente. No entanto, à medida que são acrescentadas novas instruções ao processador, o descodificador de instruções torna-se mais complexo, o que o torna mais lento.

A solução para construir processadores mais rápidos é a utilização da tecnologia RISC. Ao contrário da CISC, os processadores com tecnologia RISC são de fabrico mais simples, pois não necessitam de um descodificador de instruções. Cada bit de uma instrução abre ou fecha directamente um determinado circuito biológico do processador, o que o torna bastante mais rápido.

O seria que todos os processadores fossem baseados na tecnologia RISC, mas, há sempre um “mas”, as duas tecnologias são perfeitamente incompatíveis. Assim, se a Intel decidisse acabar com os processadores CISC e fabricar somente processadores RISC, não seríamos capazes de correr nenhum dos programas já existentes, o que nenhum de nós iria gostar particularmente.

A solução para o problema foi a apresentação de um processador híbrido, isto é, um processador RISC, mas capaz de correr instruções CISC. Assim nasceu o Pentium Pro, de que iremos falar mais à frente. No entanto, podemos adiantar que se trata de um processador RISC com um emulador CISC. Para executar instruções CISC, ele tem um descodificador interno que transforma essas instruções CISC em tantas instruções RISC quantas as necessárias, de modo a poder executar aquilo que lhe é solicitado. Esta opção da Intel mantém-se em todos os processadores seguintes ao Pentium Pro.


Passos da Execução Nativa:

Os processadores de execução nativa são aqueles que correm directamente o código x86, sem tradução para RISC. Os passos necessários à execução das instruções variam conforme o processador. No entanto, na generalidade, são os que vamos ver em seguida e em processadores mais recentes estas instruções correm em pipelines:

  • Fetch – O primeiro passo é carregar a instrução na unidade de execução. Dado que a memória é muito lenta comparada com o processador, este passo não envolve uma leitura directa da memória. Em vez disso, um circuito de controlo carrega blocos de 16 ou 32 bits de instruções ou dados, da memória directamente para uma cache primária de instruções. Estes dados estão assim disponíveis para as unidades de execução, conforme forem solicitados. Alguns processadores têm unidades de prefetch para executar esta operação.
  • Decode – A descodificação é usada para examinar a instrução carregada e determinar o seu tamanho, se requer um acesso à memória para ler dados, etc. Alguns processadores empregam múltiplos descodificadores, de modo a aumentar a sua performance.
  • Adress Generate – Enquanto algumas instruções operam em localizações de memória, outras não. Para aquelas que acedem à memória, neste estágio é gerado o endereço da localização baseado na informação dada como parte da instrução.
  • Execute – É aqui que a instrução é executada, de acordo com a informação processada nos passos anteriores.
  • Write-Back – Após a execução da instrução, é produzido um resultado que é escrito num registo interno da memória de sistema. Mas como a memória de sistema é muito lenta, na realidade esse resultado é escrito num write buffer, onde é mantido até que possa ser finalmente escrito na memória de sistema ou na cache.


Passos da Execução por Tradução x86:

Os processadores em tradução x86 são aqueles que correm instruções x86 standard, traduzindo-as em micro-instruções RISC. Este tipo de processador é muito mais complexo devido ao trabalho extra de tradução e gestão destas micro-instruções. De certo modo funciona como pequenos computadores com multiprocessamento dentro do CPU, com código especial para gerir a alocação de tarefas às diferentes unidades de execução, mais ou menos como faz um sistema operativo de multiprocessamento quando usa mais de um processador.

Tal como na execução nativa, os passos necessários à execução das instruções varia conforme o processador. No entanto, na generalidade são os que vamos ver em seguida e é de notar que estas instruções correm sempre em pipelines:

  • Fetch – O primeiro passo é carregar a instrução na unidade de execução. Dado que a memória é muito lenta comparada com o processador, este passo não envolve uma leitura directa da memória. Em vez disso, um circuito de controlo carrega blocos de 16 ou 32 bits de instruções ou dados, da memória directamente para uma cache primária de instruções. Estes dados estão assim disponíveis para as unidades de execução, conforme forem solicitados. Alguns processadores têm unidades de prefetch para executar esta operação.
  • Decode – Estes processadores empregam descodificadores múltiplos, sendo cada um deles capaz de pegar nas instruções e descodificá-las em micro-instruções. Como nenhuma das instruções x86 é executada directamente, faz sentido usar descodificadores múltiplos de modo a aumentar a performance. O tempo necessário à descodificação de uma instrução depende da sua complexidade. Instruções simples podem ser descodificadas a uma média de várias por ciclo de relógio, enquanto que outras mais complexas necessitam de mais de um ciclo cada. Qualquer endereço de memória que seja necessário é igualmente gerado nesta altura.
  • Issue/Schedule – As micro-instruções são atribuídas a uma unidade de execução. Um circuito interno optimiza esta tarefa e controla quais e para onde vão as instruções. Por vezes, esta operação denomina-se “instruction scheduling”, dado que, basicamente, é uma tarefa de agendamento de instruções, de acordo com os recursos disponíveis (unidades de execução).
  • Execute – É aqui que as micro-instruções são executadas. Normalmente são usadas múltiplas unidades de execução para aumentar a performance, onde algumas são dedicadas somente para certas instruções. Por exemplo, operações complexas de vírgula flutuante são executadas na unidade de execução de vírgula flutuante.
  • Retire – Dado que as micro-instruções podem ser executadas independentemente umas das outras e fora da sua ordem normal, temos que assegurar que não haverá problemas e que os resultados da execução são primeiro armazenados em locações temporárias. Uma unidade reúne os resultados das micro-instruções e assegura-se que o output é produzido correctamente, de acordo com as instruções x86 originais. A isso chama-se “retiring” as instruções.
  • Write-back – Após a execução da instrução, é produzido um resultado, o qual é escrito num registo interno da memória de sistema. Mas como a memória de sistema é muito lenta, na realidade esse resultado é escrito num write buffer, onde é mantido até que possa ser finalmente escrito na memória de sistema ou na cache.


Speculative Execution e Branch Prediction:

Como já vimos anteriormente, alguns processadores podem executar múltiplas instruções simultaneamente. Por vezes nem todos os resultados das execuções serão usados, devido a alterações no fluxo do programa. Isto pode ocorrer particularmente na vizinhança de branches ou ramificações, onde uma condição é testada e a sequência do programa é alterada dependendo do resultado dessa análise.

Branches são muito comuns no código x86 e poderão ser um sério problema para o pipeling, porque não podemos ter a certeza que as instruções serão executadas numa sequência linear. Pipelining é sinónimo de executar a instrução seguinte antes que a primeira esteja completa. Quando se trata de instruções de teste condicional, isto é, uma instrução tipo “if…then”, não sabemos qual é a instrução seguinte até que a instrução de teste condicional seja totalmente executada, pelo que não se sabe que instrução deverá ir em seguida para a pipeline.

Num processador menos actual, acontece parar a pipeline até que os resultados sejam totalmente conhecidos, tendo como consequência um decréscimo de performance. Processadores mais recentes tratam esse problema de um modo diferente, ou seja, executam especulativamente a instrução seguinte, com a esperança de poder usar os resultados se o branch for para o lado que ele julga que vai, daí a expressão speculative execution. Mas os processadores actuais combinam o speculative execution com uma outra técnica, o branch prediction, a qual permite ao processador, baseado no fluxo do programa e em instruções anteriores, prever com alguma precisão para que lado irá o branch.

Tomemos o seguinte exemplo:



A instrução “IF THEN” é um branch ou, melhor dizendo, uma ramificação. Até que esteja completamente executada, não sabemos se a próxima instrução será uma adição ou uma subtracção. Um processador que execute especulativamente pode arrancar tanto a adição como a subtracção simultaneamente, e pura e simplesmente esquece aquela que não interessar. Ou pode fazer uso do branch prediction para arrancar somente uma delas, aquela que ele considerar ser a mais indicada para se o resultado da instrução “IF”.

O branch prediction aperfeiçoa o manuseamento dos branches fazendo uso de uma pequena cache chamada branch target buffer ou BTB. Sempre que o processador executa um branch, ele armazena informações acerca do branch nessa área. Quando o processador encontra novamente o mesmo branch, ele é capaz de saber qual a melhor solução. Isto ajuda a manter o fluxo de instruções na pipeline e aumenta a performance. Quanto maior for o BTB, mais informação acerca dos branches é capaz de manter.

Tecnologia MMX:

MMX é a abreviatura de MULTIMÉDIA Extensions, uma tecnologia adicionada aos processadores que tem por fim simplificar o uso do multimédia. Essa tecnologia foi usada inicialmente nos processadores Pentium MMX, sendo utilizada em todos so processadores fabricados desde então.

Em termos práticos, a extensão MMX é composta por 57 novas instruções de software e algumas alterações em termos de hardware interno do processador.

No que respeita às 57 novas instruções, elas são capazes de lidar com dados agrupados de 64 bits, que podem tomar 3 formas:
  • 64 bits de uma só vez;
  • dois pacotes de 32 bits;
  • oito pacotes de 8 bits.
A manipulação de dados de áudio é geralmente de 16 bits. No entanto, alguns recursos de vídeo trabalham com sequências de 8 bits. Deste modo, as instruções MMX podem processar sons e imagens com bastante velocidade sem a necessidade de periféricos, além de poder trabalhar sons e vídeo simultaneamente.

No entanto, e como já foi referido, também há grandes diferenças a nível do hardware, já que a arquitectura interna também foi dimensionada para aumentar a performance na execução de instruções multimédia.

O barramento interno permite que várias operações de I/O possam ser executadas muito mais rapidamente. A cache interna do processador passou de 16 KB para 32 KB, sendo 16KB de cache de dados e os restantes 16 KB de cache de instruções.

Vamos ver de um modo simplificado as diferenças de operação em multimédia de um Pentium e do Pentium MMX.

A aplicação envia um comando de exibição de imagem no monitor ao sistema operativo. Esse comando é transferido pelo driver de vídeo à respectiva placa controladora, onde um circuito integrado acelerador faz o processamento da imagem. Posteriormente, este mesmo integrado faz a distribuição dos sinais para as placas de interface respectivas, isto é, fax/modem, placa de som e placa de vídeo, que por sua vez apresenta a imagem no monitor.

A aplicação envia um comando de exibição de imagem no monitor ao sistema operativo. O comando é processado pelo processador MMX, já sem o uso do integrado acelerador. Dado que o processador já incorpora as instruções multimédia necessárias, ele executa muitas das funções inerentes ao fax/modem e á placa de som e vídeo, aumentando substancialmente a qualidade e performance da imagem e do som.

Como é lógico, isto representa uma imagem muito simplista da realidade, mas permite-nos ter uma ideia da diferença entre um processador MMX e um não MMX. Não podemos também esquecer que as aplicações têm de tirar partido das instruções MMX, existentes no processador, porque, caso não o façam, o seu comportamento é idêntico à de um processador sem MMX.

Sem comentários:

Enviar um comentário