Intel Pentium 4 vs Intel Itanium Tiago Manuel da Cruz Luís Instituto Superior Técnico Grupo 10 53871 tmcl@mega.ist.utl.pt João Miguel Coelho Rosado Instituto Superior Técnico Grupo 10 53929 jmcro@mega.ist.utl.pt 1. Introdução O Pentium 4 é o primeiro processador da 7ª geração, também chamada NetBurst. Este processador fornece um ganho substancial de performance em muitas aplicações chave em várias áreas. Por exemplo, permite uma melhor experiência em áreas como o streaming de áudio e de vídeo, processamento de imagem, processamento de voz e aplicações 3D. Ele consome 55 watts de potência aos 1.5 GHz. O seu bus de 3,2 GB/segundo ajuda a fornecer uma elevada largura de banda necessária pelas aplicações actuais e futuras. Por sua vez, o Itanium foi o primeiro processador da Intel com a arquitectura IA-64 (Intel Architecture 64-bit), que incorporou técnicas inovadoras de aumento de performance. Esta família de processadores foi desenhada em cooperação com a HP e tem como objectivo responder às necessidades dos servidores de alta performance e workstations. O Itanium2 consome cerca de 130 watts a 1GHz, existindo versões Low Power a consumir 62 watts. O bus é de 6.2 GB/segundo de forma a satisfazer as necessidades dos grandes sistemas computacionais. 2. Pentium 4 Um processador rápido requere o balanceamento e aperfeiçoamento de muitas funcionalidades arquitecturais. Uma das principais vantagens desta arquitectura é o facto de permitir um aumento substancial da frequência de relógio. A figura abaixo mostra a arquitectura do Pentium 4. Como é possível observar, existem 4 secções principais: in-order front-end, lógica de execução out-of-order, unidade de execução de operações inteiras e floating point e subsistema de memória. In-Order Front End Figura 1 - Arquitectura do Pentium 4. Esta secção é responsável pelo fetch das instruções que vão ser executadas e pela sua preparação para serem utilizadas mais tarde no pipeline. Estas instruções após serem descodificadas são passadas à lógica de execução out-oforder. O in-order front-end tem como objectivo fornecer um elevado fluxo de instruções descodificadas à lógica de execução out-of-order. Trace Cache A arquitectura NetBurst possui uma cache de instruções de nível 1 chamada Trace Cache. Ao contrário das caches de instruções convencionais, esta cache situa-se entre a unidade de descodificação e de execução. Nesta localização a Trace Cache é capaz de armazenar as instruções IA-32 já descodificadas para instruções básicas no formato RISC (micro-operações), que a unidade de execução out-of-order consegue executar. O armazenamento de instruções já Página 1
descodificadas reduz o processo lento de descodificação das instruções IA-32, que equivale a uma instrução IA-32 por ciclo de relógio. Tipicamente as instruções são descodificadas uma vez e colocadas na Trace Cache, permitindo assim que a unidade de descodificação só aceda a cache L2 para descodificar a nova instrução em caso de miss na Trace Cache. Esta cache possui 6 micro-operações em cada linha e pode armazenar até 12 K micro-operações. Figura 2 - Front-End da arquitectura do Pentium 4. Perto da Trace Cache encontra-se uma ROM de microcódigo que é utilizada para lidar com instruções IA-32 complexas que requerem mais de 4 micro-operações, tais como, tratamento de interrupções e strings. As instruções provenientes da Trace Cache e da ROM são armazenadas numa fila de micro-instruções que irão ser passadas à unidade seguinte. instruções previstas pelo branch predictor são usados para realizar o fetch da cache L2. Out-of-Order Execution Logic Esta secção realiza a preparação das instruções para a sua execução. A unidade de lógica de execução utiliza um conjunto de buffers para realizar a ordenação do fluxo de instruções, de modo a optimizar o tempo perdido em instruções que têm de ser atrasadas no pipeline. Deste modo o processador irá executar o máximo de instruções em cada ciclo de relógio, mesmo que não estejam na ordem original do programa. As instruções são colocadas em duas filas, de acordo com o seu tipo. De modo a evitar conflitos na manipulação dos 8 registos existentes nesta arquitectura são criadas várias versões simultâneas de cada registo, até um máximo de 128 registos (register renaming). São também mantidas as versões mais recentes de cada registo, de modo a que as novas instruções utilizem os valores correctos dos registos. Esta técnica permite eliminar os conflitos de WAR (after-read) pois em vez de atrasar uma escrita até todas instruções de leitura terem terminado, são mantidas duas cópias deste valor, o valor antigo e o novo. Deste modo, as instruções de leitura que precedem a escrita do novo valor utilizam o valor antigo, enquanto que as restantes utilizam o novo valor. Quando todas as leituras do valor antigo foram realizadas, a cópia deste valor pode ser apagado. Esta técnica permite assim optimizar o mecanismo de execução out-of-order. Branch Prediction Como as instruções que se encontram na Trace Cache já foram descodificadas, é possível efectuar o fetch de outras instruções antes da instrução branch ter terminado com o auxílio de uma cache (BTB). O branch predictor da Trace Cache é mais pequeno do que o branch predictor do Front- End (apenas 512 entradas), pois realiza apenas a previsão das instruções branch num subconjunto de instruções que estão actualmente na cache. Esta inclui também um stack de 16 entradas de endereços de retorno de funções para permitir a sua previsão. Por sua vez, o branch predictor do Front-End realiza o fetch das instruções previstas que se encontram na cache L2, através de uma tabela de 4 Kb com o histórico das instruções branch. Caso uma instrução branch não seja encontrada no BTB é realizada a previsão estática das instruções seguintes com base na direcção do branch (salto para a frente ou salto para trás). Os endereços das Figura 3 - Lógica de execução Out-of-Order. Os vários schedulers determinam quando uma microoperação está pronta a ser executada, com base na verificação dos operandos que se encontram em registos. Após a execução da micro-operação, a unidade de Retirement é responsável pela reordenação das instruções executadas fora de ordem para a ordem original do Página 2
programa, com base nos buffers criados inicialmente pela unidade de execução out-of-order. Ela é também responsável por guardar os resultados produzidos pelas instruções. Execution Units Esta secção é responsável pela execução das instruções, que podem ser encaminhadas para 4 portas. Cada uma destas portas possui entre 1 a 3 unidades de execução. Tal como é possível observar, as unidades de ALU executam 2 instruções por ciclo de relógio. Deste modo, é possível executar um máximo de 6 micro-operações por ciclo de relógio (2 micro-operações nas portas 0 e 1 e 1 microoperação nas restantes). inclusivos, ou seja, o facto de uma linha de uma cache estar num dado nível não implica que esteja no nível seguinte. Memory Subsystem A cache de nível 2 armazena as instruções e os dados que não cabem na Trace Cache e na cache de dados L1. Ao contrário das caches de nível 1, esta cache é partilhada, ou seja, contém dados e código. O barramento externo é utilizado pela cache para aceder à memória primária quando ocorre uma falta na cache L2. Este barramento possui uma largura de banda de 3.2 Gbytes, que é conseguida através dos 64 bits de comprimento do barramento e uma taxa de transferência a 400 Mhz (obtida através de um protocolo que quadruplica a taxa 100 Mhz do barramento). Este barramento permite assim o fornecimento de uma elevada largura de banda. Capacidade 256 KBytes até 2 MBytes Tabela 2 - Propriedades da cache L2. Associati vidade Tamanho do bloco Latência Inteiro/FP 8 Vias 128 Bytes 7/7 Ciclos Política escrita back Figura 4 - Unidades de execução. Como as operações FP demoram vários ciclos de relógio, as portas 0 e 1 possuem uma unidade FP (lenta) juntamente com uma unidade rápida, de modo a permitir a execução de várias operações inteiras durante uma operação FP. É assim possível ter todas as unidades de execução ocupadas ao longo do tempo. Outro aspecto importante da arquitectura NetBurst é a latência dos acessos a memória. Isto é um aspecto muito importante nos programas com instruções IA-32, que devido ao número limitado de registos da arquitectura, realiza muitas instruções load e store. Para minimizar este facto, o acesso a cache de dados L1 é conseguido em 2 períodos de relógio neste processador de elevada frequência. Tabela 1 - Propriedades da cache da dados L1. Capacidade 8 KBytes até 16 KBytes Associati vidade Tamanho do bloco Latência Inteiro/FP 4 vias 64 Bytes 2/6 Ciclos Política escrita through Todas as caches usam o algoritmo de substituição pseudo- LRU e os níveis das caches na hierarquia são não O número de vias elevado permite obter uma boa taxa de sucesso mas aumenta a latência. Contudo, para minimizar este tempo, uma falta na cache L2 provoca 2 acessos de 64 bytes (comprimento do protocolo de acesso ao barramento) para preencher as duas metades da linha da cache (128 bytes). O preenchimento dos 128 bytes da linha da cache requer os mesmos ciclos de acesso (4 ciclos externos) que as versões anteriores dos processadores Pentium necessitavam para preencher uma linha de 32 bytes da cache. Este aumento da latência faz com que o pre-fetching existente seja um factor importante na performance. O prefecther da cache L2 faz o pedido das 2 linhas da cache seguintes (256 bytes) ao acesso actual. Este possui ainda uma certa inteligência que lhe permite monitorizar o histórico dos cache miss para tentar evitar pré-fetches desnecessários (que ocupam espaço na cache e ocupam o barramento externo). Este pre-fetcher é muito útil no streaming de ficheiros multimédia, uma vez que estes não provocam muitos acessos a cache. O pre-fetcher pode neste caso facilmente detectar o padrão de cache miss e carregar com antecedência os dados, levando a um aumento de performance neste tipo de aplicações. Pipeline O Pentium 4 possui um pipeline com 20 estágios que é capaz de executar 3 micro-operações em cada ciclo de relógio. O maior número de estágios permite que o Página 3
processamento em cada estágio seja menor (menos portas lógicas), permitindo assim ao processador trabalhar com frequências mais elevadas. Figura 5 - Estágios do pipeline do Pentium 4. Um dos aspectos mais interessantes neste pipeline é o facto de a Intel ter dedicado 2 estágios do pipeline para a transferências de dados no chip. Isto realça a ideia de que o factor limitador no desenho dos circuitos integrados actuais é o tempo de propagação dos dados nas ligações do chip. Contudo este pipeline profundo levanta alguns problemas de desempenho. Um desses problemas é a previsão de saltos, que provocam stalls na execução do pipeline quando esta previsão falha. Devido ao número de estágios existe uma perda considerável de instruções executadas. Outro problema prende-se com o uso de instruções IA-32, pois é necessário em certos casos que a Trace Cache passe o controlo para a ROM de micro-código, tal como já foi referido anteriormente. Este facto provoca atrasos no pipeline que levam à diminuição do desempenho. O Pentium 4 introduziu uma nova funcionalidade no seu pipeline que permite que o escalonamento de instruções dependentes de um load coincida com a chegada dos dados da cache de dados L1. Estas instruções são canceladas no caso de ocorrer um cache miss e repetidas mais tarde, após a chegada dos dados da cache. Contudo, apesar de apenas as instruções dependentes da instrução load serem repetidas, esta técnica depende do padrão de acessos a memória pelas instruções load. O pior caso verifica-se quando uma aplicação realiza operações em dados que se encontrem espalhados pela memória, o que faz com que haja uma perda de performance. Hyper-Threading Esta tecnologia permite que o processador efectue mais rapidamente a troca de contexto entre as tarefas, permitindo assim aproveitar os tempos em que o processador se encontra suspenso (devido a um cache miss ou erro na previsão de um branch por exemplo). Esta troca rápida é conseguida através da duplicação da parte do processador responsável por armazenar o estado de um processo. Figura 6 Pipeline do Pentium 4 com Hyper-Threading. Deste modo é possível que um único processador realize, por exemplo, o fetch e execução de dois fluxos de execução independentes simultaneamente. Contudo este mecanismo introduz alguma complexidade no processador e caso existam duas aplicações que executem instruções semelhantes não permite obter o nível de paralelismo esperado. 3. Itanium 2 Este processador é destinado a sistemas que requerem uma grande disponibilidade, segurança e fiabilidade. Ao contrário dos sistemas Pentium, não existe nenhuma execução out-of-order e são efectuadas o máximo de optimizações possíveis em tempo de compilação, retirando assim muita da complexidade do hardware. A arquitectura do Itanium é baseada em VLIW (Very Long Instruction Word), mas propriamente chamada de EPIC (Explicit Parallel Instruction Computing) e pretende tirar partido do facto de existirem muitas instruções sem dependências de dados que podem ser executadas em paralelo. Geralmente os processadores com a arquitectura VLIW têm como desvantagem estarem muito dependentes do número de unidades de execução, latências, número de instruções paralelas e outros pormenores de arquitectura. Com o Itanium foi realizado um esforço com o objectivo de reduzir essa dependência. No estando este encontra-se bastante dependente de alguns factores, como as unidades de execução que estão limitadas a alguns templates. In-Order Front End Cada instrução é composta por 41 bits, divididos pelo opcode, quatro operandos e um qualifying predicate (qp). Caso este predicado seja falso a instrução não é executada. Página 4
Tabela 3 - Constituição das instruções do Itanium. 40 37 36 27 26 20 19 13 12 6 5 0 Opcode Oper 4 Oper 3 Oper 2 Oper 1 qp Existem seis classes de instruções: A (operações de inteiros com ALU), I (operações de inteiros sem ALU), M (memória), B (saltos), F (floating point) e X (instruções que ocupam o espaço de duas instruções). Como é característico de uma arquitectura VLIW, as instruções são agrupadas em vários bundles de instruções. Assim, cada bundle possui 16 bytes, três instruções e um template de 5 bits. Os templates servem para indicar ao processador como cada instrução deve ser executada e incluem informação sobre o grupo das instruções. Um grupo é um conjunto de instruções (que pode ser constituído por mais do que um bundle) decididas em tempo de compilação que podem ser executadas em paralelo. O conceito de grupo é um factor muito importante, pois retira a necessidade de recompilação do código no caso de se alterar o número de instruções paralelas (diminuir nos Low Voltage, ou até aumentar). Pipeline A pipeline do Itanium é constituído por 8 fases in-order, com store-to-load forwarding e que permite executar em simultâneo 6 instruções (2 bundles). A sua estrutura é bastante simples, e permite que um stall em alguma instrução em qualquer fase do pipeline, pare todas as fases anteriores incluindo instruções que estão a correr em paralelo, evitando assim flushs desnecessários. Para executar as 6 instruções em paralelo existem 11 unidades de execução. Estas unidades encontram-se divididas em 4 unidades de memória, 2 de inteiros, 2 de floating point e 3 de branch. As duas primeiras fases do pipeline (front-end) são utilizadas para realizar o fetch das instruções antes de serem utilizadas pelo back-end. Existe um buffer de instruções que permite guardar 8 bundles para utilização. Combinando este buffer com as caches de baixa latência e um bom sistema de branch prediction (descrito adiante) é possível garantir que raramente existem stalls de pipeline por falta de instruções. Predication Utilizando os registos de predication e o pq é possível remover completamente os branchs, executando ambos em simultâneo e apenas activar os resultados de um deles. Multi-Way Branch Esta técnica é utilizada para evitar testes de branching sucessivos, tornando possível num único ciclo (6 instruções) efectuar até três testes e os branch respectivos, utilizando o predication para activar apenas um branch. Early Branch Condition Testing É possível separar o teste da condição do próprio branch, efectuando o teste muito antes de este ser efectuado. Quando chega ao momento do salto é possível saber apenas utilizando a prediction se o salto é feito ou não. Branch Hinting É possível indicar se um branch é efectuado muito ou poucas vezes, melhorando a capacidade de pre-fetch de instruções. Branch Registers No caso de branchs indirectos é complicado saber o destino do salto até ao momento de execução. No entanto o compilador pode antes de tempo especificar num dos 8 registos de branch qual o endereço do branch antes de o efectuar. 64Bits IP Relative Branching via Immediate field Semelhante à técnica de Branch Registers, mas utilizados explicitamente para efectuar o prefetch. Loop Control Utiliza instruções especiais de branching que permitem, em hardware, calcular quando é que os ciclos vão terminar antes do tempo. Isto pode ser feito tanto no caso do ciclo ter um número fixo de iterações ou apenas sabendo a condição de paragem. É também possível especificar se o salto é efectuado muito ou poucas vezes (ex: br.many) Apesar da existência deste número elevado de técnicas, não é possível prever com 100% de eficiência todos os branch, sendo necessário verificar se foi efectuado o salto correcto. No entanto consegue-se garantir um número reduzido de erros e também que o tempo de penalidade de uma previsão errada são muito pequenos (1, 2 ou 6 ciclos). Branch Prediction Uma grande diferença em relação ao Pentium 4 é a forma como é realizada a previsão dos branchs. No Itanium existe um grande número de técnicas que permitem em tempo de compilação ajudar o processador a ter mais informação sobre os branchs. Entre estas técnicas temos: Página 5
In-Order Back-End Figura 7 - Exemplo da técnica de branch Multi-Way. Speculation Durante a execução de qualquer programa a quantidade de leituras de memória influenciam fortemente os tempos de paragem do pipeline. De modo reduzir o impacto destas paragens, no Itanium é possível fazer leituras de memória antes do tempo, mesmo que existam dependências desconhecidas pelo meio. A especulação permite permitir o impacto da latência no acesso a memória. Existem dois tipos de especulação: controle e dados. Na de controlo, mesmo não sabendo o resultado de um branch, é efectuado a leitura que se segue, e no caso de erro é executado código de recuperação (também gerado pelo compilador). Embora em caso de falha exista uma penalidade de recuperação, esta será menor que esperar pela latência da leitura. Na de dados, são efectuados loads avançados, tal como na de controlo, podendo existir escritas com destinos desconhecidos pelo meio. Esta informação é guardada numa estrutura ALAT (Advanced Load Address Table) de 32 entradas. Quando chega ao momento real da leitura, é verificado na ALAT se ainda se encontra válido, de modo a poder ser utilizado sem latência. Se não for válido, é efectuada a leitura tal como seria normal, sendo muito provável que o valor se encontre na cache. Tabela 4 - Exemplo de especulação de dados. Original Store(storeAddr, data)... Load(loadAddr, target) Use(target) Speculation advload(loadaddr, target)... Store(storeAddr, data) advcheck(target, recovery) Use(target) Devido ao facto de não ser possível saber em tempo de compilação se loadaddr e storeaddr são iguais, é realizada a sua especulação. Tal como no Pentium 4 existe uma fase no pipeline reservada para renomear os registos. No entanto, existe uma grande diferença, uma vez que esta técnica é utilizada para criar o stack frame de cada função, através da utilização de registos. Nesse conjunto de registos existem 128 registos inteiros, dos quais apenas 32 são fixos. Os restantes são reservados em stack (mapeados em memória, mas instanciados em registos verdadeiros ) consoante a necessidade. Cada stack frame encontra-se dividida dinamicamente em três partes, local, input e output. Quando um A chama B, o output de A passa a ser o input de B e é reservado o espaço necessário para as restantes duas partes. A grande vantagem deste sistema é reduzir a quantidade de leituras e escritas de memória, pois os acessos a memória (registos mapeados em memória) podem ser feitos, não só quando são necessários, mas quando existe oportunidade para os fazer, melhorando a eficiência. Devido ao facto do Itanium ser um processador RISC possui um grande número de registos, permitindo assim diminuir a necessidade de transferências de memória. A distribuição dos registos principais é feita conforme a seguinte tabela. Tabela 5 - Distribuição dos registos do Itanium. Tipo Quantidade Tamanho (bits) Integer 128 64 Floating Point 128 82 Predicate Registers 64 1 Branch 8 64 De Aplicação 128 64 Memory Subsystem No Itanium existem três níveis de caches com capacidade de transferência entre cada nível de (incluindo entre L1 e processador) 32 bytes por ciclo, ou seja, 32Gbytes/s. Em tempo de compilação é possível especificar cache hints, que permitem colocar antecipadamente em cache os dados respectivos. Tabela 6 - Propriedades das caches do Itanium. Tipo Tamanho Vias Tamanho Blocos Tempo Acesso Política escrita Página 6
Tipo Tamanho Vias Tamanho Blocos Tempo Acesso L1I 16 Kbytes 4 64 bytes 1 L1D 16 Kbytes 4 64 bytes 1 L2 256 Kbytes 8 128 bytes (leituras parciais) 5, 7, 9+ Política escrita Through Through Back cache estão os dados. Isto permite, em caso de sucesso, aceder aos dados em 1 ciclo. A TLB de dados de nível 1 apenas possui 2 portas porque apenas é utilizada para inteiros. A TLB de nível 2 é unificada (instruções e dados), possui 128 entradas e é completamente associativa. Os acessos a unidades de floating point são feitos através do nível 2. Embora o tempo de acesso a floating points seja mais elevado, na prática é preferível optimizar a leituras de inteiros porque são muito mais utilizados. L3 3 Mbytes 12 128 bytes (leituras completas) 12+ Back No caso de falta na cache L3 é utilizado um barramento externo de acesso à memória. Este barramento possui uma largura de banda de 6.4GB/s, que é conseguida através de um comprimento do barramento 128 bits de e uma taxa de transferência a 800 Mhz (400 Mhz double-pumped). Como consequência directa da velocidade do barramento, não só diminui o tempo de latência do acesso á memória, como também melhora o funcionamento deste processador em sistemas multi-processador, como é comum em servidores. Devido ao pipeline ser bastante simplificado, é possível ter um sistema de memória bastante mais complexo. O sistema possui 64 bits de endereço virtual e 50 bits de endereços físicos, permitindo assim 1024TB de endereços. Figura 8 - Organização dos níveis de caches do Itanium. Ambas as TLB de nível 1 do sistema utilizam um sistema de prevalidated-tags. Este sistema baseia-se no facto de se não existir uma entrada na TLB, então não vai ser possível aceder ao valor cache. Assim, a TLB possui o mesmo número de entradas da cache L1 e guarda em que via da 4. Comparação entre Pentium 4 e Itanium 2 O principal objectivo do Pentium 4, muito devido ao mercado a que se destina, é atingir uma elevada frequência de relógio, visto que a maioria dos utilizadores considera este valor de frequência como um elevado poder de processamento. Estes valores de frequência foram conseguidos através do longo pipeline. Contudo, este pipeline longo torna o processador mais complicado e faz com que este tenha um conjunto de buffers mais elevado. Outro facto que complica o hardware do Pentium 4 relativamente ao Itanium é o facto de este ser um processador out-of-order, o que leva a que as instruções store só possam ser finalizadas após terem sido reordenadas de acordo com o programa original. Devido ao pipeline longo do pentium 4 são necessários muitos ciclos de relógio até os stores serem completados. Para permitir a utilização dos valores das instruções de store pendentes, o Pentium 4 utiliza um buffer de 24 posições (que corresponde ao número máximo de instruções store que podem existir em simultâneo no pipeline) com esses valores, de modo a poderem ser utilizados pelas instruções load (store-to-load forwarding). Contudo este processo não é aplicado caso o número total de bytes necessários pela instrução load não estiver na instrução store pendente, o que leva a uma perda de performance. Em comparação com o Itanium 2 o processador Pentium 4 fornece um número reduzido de registos, apenas 8 registos genéricos, o que faz com que haja um maior número de acessos a memória O facto de o Pentium 4 ser um processador CISC faz com que exista um aumento na complexidade e no tempo de execução da instrução devido a sua descodificação para o formato RISC. Contudo, a Trace Cache permitiu diminuir o peso desta operação. Por exemplo, no caso dos ciclos das aplicações, as instruções do ciclo apenas necessitam de ser descodificadas na primeira iteração. De modo a optimizar o espaço ocupado pelas instruções descodificadas na Trace Cache, o seu branch predictor e o branch bredictor do front-end apenas permitem que sejam armazenadas instruções que sejam realmente executadas. Página 7
As duas unidades ALU do Pentium 4 funcionam ao dobro da velocidade das restantes, o que permite concluir que este processador se encontra optimizado para a execução de instruções simples. Contudo, ele também fornece um grande número de instruções que optimizam as aplicações multimédia (Streaming "Single Instruction, Multiple Data" Extensions). Uma desvantagem que o Itanium apresenta em relação ao Pentium 4 é a utilização do stack das funções em registos., de modo a optimizar as frequentes mudanças de contexto existentes Embora seja muito mais eficiente em termos de tempo de acesso (devido às caches), existe uma limitação de 128 posições de 64 bits para cada stack (que inclui variáveis de input, de output e locais) enquanto que o stack do Pentium 4 é configurável para cada programa e sem grandes limitações. A arquitectura do Pentium 4 (x86) é mais antiga que a do Itanium 2, portanto não possui muitas das suas vantagens de arquitectura. No entanto, encontra-se muito bem distribuída pelo mundo como base computacional, existindo bom suporte e software optimizado. Por outro lado, o Itanium apresenta excelentes capacidades para sistemas back-end. As suas vantagens de performance, estabilidade, disponibilidade e segurança são o ideal para situações criticas de negócio. Os sistemas Itanium possuem também mais protecções a nível de segurança de dados, chamadas de RAS (reliability, availability, serviceability). Este aspecto da segurança é muito importante nos sistemas a que este processador se destina. 2 a 4 processadores (sendo possível, mas não muito comum, 32). Isto deve-se principalmente devido ao tamanho do espaço de endereçamento, velocidade do barramento e segurança de dados. Devemos também lembrar que estes sistemas não são completamente distintos. Embora um grande factor decisivo seja o elevado preço dos Itanium, é possível combinar sistemas front-end com Pentium 4 com os back-end com Itanium2 optimizando os resultados. Para facilitar esta transição, os processadores Itanium podem realizar a emulação de instruções x86, tanto em hardware como em software. No entanto, a emulação por hardware é bastante lenta, devido à ausência de um motor out-of-order e das ajudas feitas pelo compilador. Assim, a emulação por hardware vai desaparecer nas próximas versões do Itanium, ficando apenas disponível a emulação por software. Apesar do que seria previsto, esta emulação por software aplica ao código x86 as optimizações do Itanium, conseguindo-se assim um desempenho maior. Referências [1] Intel Corp, The Microarchitecture of the Pentium 4 Processor [2] McNairy, C., Soltis, D., Itanium 2 Processor Microarchitecture [3] - Kelley, S., e Lu, Z. Intel Pentium 4 Processor [4] Itanium Solutions, Itanium 2 based solutions and the x86 architecture [5] HP Corp, Inside the Intel Itanium 2 Processor [6] Intel Corp, IA-32 Intel Architecture Reference Manual [7] Almeida, T., Ventura, J., Intel Pentium 4 [8] Maranho, F., Diniz, D., Arquitectura Itanium 2 Figura 9 - Características RAS do Itanium 2 vs x86. A adicionar a estas vantagens temos ainda a capacidade de multi-processamento dos sistemas Itanium, que permitem interligar com facilidade muitos processadores (até 512), enquanto que o Pentium 4 apenas está preparado para ligar Página 8