Analisando a arquitetura do processador AMD K8 utilizando a ferramenta de simulação PTLsim com benchemarks SPEC 2000 e SPEC 2006 Eduardo Machado Real UEMS – Universidade Estadual de Mato Grosso do Sul Nova Andradina – MS, Brasil [email protected] Francisco Sanches Banhos Filho UNEMAT – Universidade Estadual de Mato Grosso Colíder – MT, Brasil [email protected] RESUMO Este artigo descreve a simulação de benchmark em uma arquitetura superescalar utilizando a ferramenta PTLsim. O PTLSim é um simulador com acurácia de ciclos e máquina virtual para o conjunto de instruções x86 e x86-64. A máquina utilizada será a Turion X2 - 2.0 Ghz de 64 bits. Os experimentos realizados compreendem a execução de alguns benchamarks da classe SPEC2000 e SPEC2006, onde é possível o levantamento de métricas que possibilitam uma análise comparativa de resultados. Palavras chaves: simulação de processador, benchmarks e PTLsim. 1 Introdução O uso de um simulador de microprocessadores auxilia no projeto de processadores por permitir que o projetista possa testar várias arquiteturas diferentes. A utilização de protótipos aumenta os custos e tempo necessário na construção de uma nova arquitetura, ou seja, na fase de projeto de microprocessadores e mesmo para estudos avançados sobre tais componentes, a simulação é um processo (recurso) importante e possibilita uma gama de testes na definição de uma nova arquitetura. A busca por processadores cada vez mais rápidos segue três principais tendências: o Superpipeline, a técnica Superescalar (replicação dos componentes internos do processador de modo que se possa colocar várias instruções em cada estágio do pipeline) e o escalonamento dinâmico do pipeline ou pipeline. (FREITAS, 2003) Atualmente existem alguns simuladores de microprocessadores, porém os mais utilizados são os simuladores de desempenho, que simulam a micro-arquitetura ou partes da micro-arquitetura de microprocessadores, e são orientados a execução, onde o simulador executa um benchmark para avaliação de desempenho. Especificamente este estudo investigou a ferramenta PTLsim, com base em Yourst (2007), afim de determinar a factibilidade para modelagem e simulação de processadores com acurácia de ciclos. O PTLsim é uma ferramenta (programa) de simulação com acurácia de ciclos para microprocessadores baseados em arquitetura x86 com conjunto de instruções x86 e x86-64. Esta ferramenta é diferente dos outros simuladores com de mesma funcionalidade, pois ele executa diretamente na mesma plataforma que está sendo simulado. Ele possui duas versões principais, a clássica onde as instruções são executadas somente no espaço de usuário e que será utilizado nesse trabalho, e a versão PTLSim/X que simula processadores em modo full-system. Os experimentos consistiram na execução de alguns Benchmarks da classe SPEC2000 e SPEC2006 [10], para a avaliação de algumas métricas tais como taxa de transferência entre as Caches de nível 1 (L1) e nível 2 (L2). Esses experimentos foram realizados utilizando a configuração padrão do PTLSim em um processador AMD K8. Os resultados mostraram que é possível obter diversos detalhes da execução de processadores utlizando o PTLSim. 1.1 A ferramenta PTLsim Simuladores PTLsim modelam um sistema superescalar (e multiprocessado) com conjunto de instruções x86-64 a um nível de detalhe configurável. Ele fornece um modelo altamente detalhado e configurável de uma microarquitetura similar ao do Pentium 4 da Intel, AMD K8 ou Intel Core 2. Quando o PTLsim foi lançado como software open-source em 2005, sua versão clássica executava instruções de 32 ou 64 bits single-threads somente no espaço de usuário (userspace). Além de ser o único simulador x86 código-fonte aberto com acurácia de ciclos à disposição, o PTLsim suporta características únicas, incluindo a cosimulação. Atualmente é a única ferramenta de domínio público disponível para a modelagem de arquiteturas x86. Uma vantagem da abordagem utilizando PTLsim é a possibilidade de comparar uma arquitetura experimental com arquiteturas x86 comerciais utilizando o mesmo conjunto de instruções e, além de agilizar a obtenção de uma ferramenta que simule as características do processador K8, possibilita aumentar as possibilidades de avaliações experimentais com esse processador, uma vez que existem várias aplicações compatíveis com o simulador PTLsim assim como vários modelos de processadores já implementados em sua infraestrutura de simulação. Outra característica atrativa para adoção de PTLsim como plataforma básica para simulação de processadores experimentais reside na sua exibilidade para configurar clusters e unidades funcionais da microarquitetura. Essa capacidade de configuração possibilita indicar latências multiciclo para clusters, mapeamento entre unidades funcionais e clusters, assim como latências de micro-operações (μop). O PTLsim possibilita também configuração de largura dos registradores de pipeline, largura de banda de barramentos e respectivas latências. 1.2. Processadores com emissão múltipla de instruções (multiple-issue) Um processador superescalar típico busca e decodifica várias instruções por ciclo, tornando necessário verificar a não existência de dependência entre elas. As instruções são executadas fora da ordem mantendo a semântica seqüencial definida pelo programador. (FREITAS, 2003) As principais características das arquiteturas superescalares são de possuir técnicas para determinação e redução de dependência entre os dados e instruções, capacidade de buscar várias instruções em um ciclo, possuir mecanismo de previsão de desvios condicionais, capacidade para despachar várias instruções em um ciclo, possibilitar o controle e verificação do ordenamento correto das instruções executadas fora de ordem, possuir estratégias para comunicação de dados, através da memória, empregando load / store, memória hierárquica, múltiplas unidades funcionais e recursos para execução paralela de múltiplas instruções. (FREITAS, 2003) As arquiteturas de processadores superescalares exploram o paralelismo de instrução. As múltiplas unidades funcionais independentes permitem despachar simultaneamente mais de uma instrução por ciclo. Na execução, processadores superescalares variam o número de instrução por ciclo de clock escalando-as de modo estático ou dinâmico. As máquinas superescalares tentam paralelizar a execução de instruções independentes, em cada estágio do pipeline. Caso as instruções possuam dependências, um menor número de instruções será executado por ciclo. Quando cada unidade pode ser colocada no pipeline (Multiply Pipeline) e cada estágio de pipeline leva menos ciclos para completar a operação, na arquitetura superescalar, se todos os estágios estão ativos em paralelo no pipeline, obtêm-se a finalização de mais de uma instrução por ciclo Dessa forma esses processadores podem sustentar uma taxa de execução maior que uma instrução por ciclo; o que resulta em um ganho de desempenho significativo em relação às arquiteturas de pipeline escalares, capazes de executar apenas uma instrução por ciclo. Para garantir o ganho potencial das arquiteturas superescalares em relação às outras, é necessário manter as unidades funcionais sempre ocupadas, ou seja, despachar o maior número de instruções possível a cada ciclo. Métodos de previsão de desvios, execução especulativa e escalonamento de instruções são objetos de interesse na melhoria das arquiteturas superescalares. A execução em pipeline superescalar também aumenta o throughput de instruções. Porém, as possíveis limitações dessa arquitetura não serão abordadas neste tópico. 2 Simulação de um processador amd k8 utilizando a ferramenta Ptlsim Esta seção detalha brevemente a arquitetura do processador utilizado nos experimentos, os benchmarks que foram executados, e ao final, os resultados e discussões de acordo com métricas que foram escolhidas. Aqui não foram inseridos os resultados de todos os experimentos devido a finalidade do estudo, porém podem ser obtidos com os autores deste artigo. 2.1 Processador AMD64 / K8 A arquitetura utilizada neste trabalho foi a geração do processador K8 da AMD64. Este processador tem como base a tecnologia x86-64, uma tecnologia que permite a execução de aplicativos de 32 bits sem necessidade de qualquer tipo de emulação e sem perda de desempenho, além de oferecer suporte a uma nova geração de aplicativos de 64 bits. (ROMANO, 2005 & AGNER, 2012) O projeto da plataforma AMD64 incluiu o desenvolvimento de uma nova tecnologia de conexão ponto a ponto, com alta largura de banda e baixas latências, o HyperTransport. Nos processadores AMD64 o HyperTransport (ajuda a reduzir a quantidade de barramentos em um sistema, o que pode diminuir os gargalos) e a controladora de memória integrada ao processador substituem o FSB (Front Side Bus), eliminando gargalos, melhorando o desempenho e permitindo alta escalabilidade em servidores. (ROMANO, 2005 & AGNER, 2012) Romano (2005) inclui ainda: o SOI (silicon-on-insulator); Proteção de ECC (Error Correcting Code); Aprimoramento na previsão de desvios para maior precisão ao antecipar chamadas de instrução; Estruturas TLB avançadas para melhor gerenciamento da memória em cargas de trabalho complexas; Dois estágios de pipeline adicionais para escalabilidade da frequência; Adição de instruções SSE21 (e SSE32 a partir da revisão E); IPC mais alto, atingido por meio de importantes recursos adicionais, como TLBs maiores, filtros de descarga e algoritmos aprimorados de previsão de desvio. Esses processadores podem trabalhar nos modos: Legacy Mode (Sistema Operacional e aplicativos de 32 bits); Long Mode Compatibility (Sistema Operacional de 64 bits e aplicativos de 32 bits) e Long Mode 64-Bit (Sistema Operacional e aplicativos de 64 bits) A controladora de memória está integrada ao processador no chipset da placa-mãe não existindo mais o FSB (Front Side Bus). As memórias se conectam diretamente à controladora de memória integrada do processador, através do barramento de memória, e ainda, se comunica com o núcleo do processador na mesma frequência do processador. Seus Registradores de Uso Geral tem capacidade de armazenar números de até 64 bits, número 4,3 bilhões de vezes maior que os registradores de 32 bits podem suportar, além disso, possuem oitos novos Registradores de Uso Geral de 64 bits (totalizando 16), e mais oitos registradores SDIM (Single Instruction Multiple Data) que são utilizados pelas instruções SSE (Streaming SIMD Extensions), SSE2, SSE3. (AMD, 2011) Além disso, permite endereçar até 1 Terabyte de memória física e 256 Terabytes de memória virtual. (RODRIGUES, 2005) No seu núcleo o AMD64 é um processador superescalar de 9 vias (ou seja, permite teoricamente a execução de 9 instruções simultaneamente) de execução fora-de-ordem. (ROMANO, 2005) Estas 9 unidades de execução estão agrupadas em 3 unidades de inteiros (Unidades Lógicas e Aritméticas), 3 Unidades de Geração de Endereços (AGU’s: Adress-Generation Units) e 3 Unidades de Cálculo de Ponto-Flutuante. E ainda, converte cada instrução x86 em uma ou mais operações RISC internas [ROP’s]. Após as primeiras etapas do pipeline, o AMD64 é no fundo um processador RISC, e não tem qualquer noção do que são instruções x86 ou do estado da máquina. (ROMANO, 2005) O AMD64 é capaz de descodificar até 3 instruções x86 e enviar 9 ROP’s (RISC operations) por ciclo de relógio, no melhor cenário (na eventualidade de cada uma das ROP’s ser enviada para cada uma das 9 unidades de execução). A maioria das ROP’s executa diretamente no hardware, mas mesmo após conversão, algumas operações x86 são demasiadas complexas para tal. Estas últimas são detectadas e emuladas por rotinas na microROM do processador. (ROMANO, 2005 & STOKES, 2005). 2.1.1 Arquitetura AMD64 / K8 O K8 é um processador RISC que decodifica as instruções CISC em tempo de execução e atende as instruções MMX, Extended 3DNow!, SSE, SSE2, SSE3, AMD64. O pipeline do AMD64 tem 12 etapas. Sendo que a arquitetura K8 possui 2 níveis de pipeline a mais que o K7, estes foram adicionados para que se possa atingir clock mais altos. (HOFFMAN ET al., 2008 & AGNER, 2012) Tabela 1 – Estágios do pipeline Veja os passos do pipeline: (STOKES, 2005) • Fetch 1 e Fetch 2: Nestes dois estágios 16 bytes (equivalente a aproximadamente cinco instruções x86) são trazidos de uma vez da Cache L1 de instruções e colocado em um buffer no seu front end. A fase de Fetch foi quebrada em duas fases em relação ao Atlhon. Isso foi feito para ajudar a equilibrar a velocidade do clock com a latência de acesso à cache L1. • Pick: Estes 16 bytes são transferidos para um buffer de 32 bytes, unindo-se os novos 16 bytes com 16 bytes já previamente buscados. O processador então procura neste grupo de 32 bytes de instruções os limites entre cada instrução e posteriormente alinhadas. Finalmente as instruções são classificadas em 1 ou 2 tipos - aquelas que podem ser decodificadas diretamente pelo decodificador, e aquelas que precisam ser decodificadas pelo “microcode engine” - e então ser alinhadas e enviadas para a fase de decodificação. Todo este processo é feito em apenas 1 ciclo de clock. Isso é possível pois o processador “trapaceia” usando uma pré-decodificação que é adicionado quando a instrução é buscada da L1. • Decode 1 e Decode 2: Existem 2 tipos de hardware de decodificação – a decodificação direta feita pelo Fastpath decoder e a decodificação através do microcode engine. Ambas traduzem instruções x86 em instruções internas no formato RISC-like, que é mais fácil para o processador de execução administrar. O Fastpath decoder traduz cada instrução em no máximo 2 UOPS. Isso é, este decodificador encarrega-se das instruções x86 mais simples. O Fastpath decoder pode traduzir até 3 instruções x86 de uma vez em até 3 UOPS por ciclo. O microcode decoder encarrega-se das instruções que são traduzidas em mais do que 2 UOPS. Ele pode trabalhar em apenas uma instrução x86 de cada vez, e pode produzir até 3 UOPS por ciclo. • Pack, Pack/Decode e Dispatch: Uma vez que os decodificadores produziram um conjunto de Macroops, estas operações são agrupadas 3 de cada vez em “grupos de despacho”. Uma vez as instruções agrupadas, algum processo final de decodificação é feito e então cada grupo é enviado para o buffer de reordenação. Por fim as MacroOps são despachadas para a unidade de execução, onde a sua execução é agendada. • AGU/ALU: Nessa etapa é feita a execução propriamente dita. • Data Cache 1 e Data Cache 2: Nessa etapa os dados são gravados no cache L1 de dados. 2.1.2 Arquitetura do Turion O Turion 64 X2 é a solução dual core para laptops da AMD. A arquitetura mono núcleo pode ter entre 512KB ou 1MB de cache L2, Enquanto os processadores de duplo núcleo podem ter de 256KB até 1MB de cache L2 por núcleo. Isso é interessante, pois os processadores Core Duo e Core 2 Duo da Intel compartilham a cache L2 entre os núcleos. (HOFFMAN et al., 2008) O Turion tem doze estágios. Suporta memórias DDR2 entre 400 à 800MHz, 40bits de endereços físicos e 48bits de endereços virtuais. Possui dezesseis registradores de inteiros de 64bits, dezesseis registradores de 128bits para instruções SSE / SSE2 / SSE3. (HOFFMAN et al., 2008) 2.2 Características do processador utilizado Abaixo estão as informações da plataforma utilizada para simulação: Processador: AMD Turion 64 X2 Frequência de clock: 2GHz DTLB: 32 KB em 32 vias ITLB: 32 KB em 32 vias L1D: 64 KB, 64 bytes/linha, 2 vias L1I: 64 KB, 64 bytes/linha, 2 vias L2: 512 KB, 64 bytes/linha, 16 via 2.3. Suite de simulação No estudo foram utilizados benchmarks de inteiros e ponto flutuante, compilados no gcc Linux. Veja a figura 1: Li C INT 2000 Combinatorial Optimization Compression C C INT INT 2000 2000 183.equake Seismic Wave Propagation Simulation C FP 2000 188.ammp Computational Chemistry C FP 2000 C FP 2006 C INT 2006 C INT 2006 C FP 2006 C FP 2006 175.vpr 181.mcf 256.bzip2 433.milc 456.hmmer 458.sjeng 470.lbm Physics / quantum chromodynamics (QCD) Hidden Markov Models (profile HMMs), modelos estatísticos de alinhamentos de seqüência múltipla, usados em biologia computacional para procurar padrões em seqüências de DNA. Artificial Intelligence (game tree search & pattern recognition) Computational Fluid Dynamics, Lattice Boltzmann Method 999.specrand Mine Canari SP EC ia eg or ng u cr iç es D C at ag em ão k en ch m ar B FPGA Circuit Placement and Routing, gera código para um processador AMD, é executado como um compilador habitado com muitas flags de sua otimização. Figura 1 – Conjunto de benchmarks executados Esses programas são benchmarks de inteiro e de ponto flutuante e compõem o SPEC (The Standard Performance Evaluation Corporation) 2000 e SPEC 2006. Os benchmarks da classe SPEC são escritos em uma plataforma neutra, nas linguagens de programação C ou Fortran, e as partes interessadas podem compilar o código usando o seu compilador preferido para a sua plataforma, mas não podem alterar o código. É possível executá-los em diferentes plataformas e para diversos fins, e com isso obter estatísticas de desempenho do ambiente como resultado. Basicamente o SPEC contém duas suites benchmark: CINT2000/2006 para medir e comparar o desempenho de computação intensiva de inteiro, e CFP2000/2006 para medir e comparar o desempenho de computação intensiva de ponto flutuante. 2.6. Análise dos Resultados O PTLSim pode gerar vários números estatísticos ao simular arquiteturas. É possível obter o comportamento do processador em um determinado ciclo de execução do programa, e com isso obter estatísticas em nível de estágios de pipeline. A Tabela 1 mostra o comportamento de algumas estatísticas relacionadas ao front-end do compilador, responsável pela decodificação e alocação das micro-instruções, bem como o renomeamento dos registradores. Tabela 1 - Alloc Benchmark 175.vpr 256.bzip2 183.equake 188.ammp 433.milc 456.hmmer 458.sjeng 470.lbm 999.specrand br 18,38% 5450 18,45% 5443 18,57% 5386 18,57% 5401 18,35% 5519 18,79% 5491 18,44% 5443 18,64% 5610 18,67% 5646 sfr 7,70% 2283 7,74% 2284 7,79% 2260 7,65% 2225 7,89% 2374 7,95% 2323 7,70% 2272 8,11% 2439 8,09% 2446 reg 58,25% 17276 58,38% 17222 58,21% 16886 58,34% 16968 58,03% 17456 57,48% 16795 58,33% 17216 57,07% 17175 57,14% 17285 ldreg 15,67% 4648 15,43% 4553 15,44% 4478 15,44% 4490 15,73% 4730 15,78% 4611 15,54% 4586 16,18% 4868 16,11% 4872 total 29657 29502 29010 29084 30079 29220 29517 30092 30249 Essas estatísticas são interessantes para se avaliar de maneira eficiente o comportamento das unidades funcionais. Essas estatísticas foram retiradas após o commit de 10000 instruções da execução dos benchmarks. A métrica Alloc (ver Tabela 1) resume a alocação dos recursos para cada micro-instrução. A segunda coluna, br, mostra o percentual e o número de micro-instruções que são um desvio e foram alocadas para algum recurso de desvio (isso inclui a possibilidade da alocação de registrador físico de destino). A terceira coluna, sfr, mostra as micro-instruções que são store e são alocados a alguns registradores de forwarding (SFR). A coluna Reg mostra o percentual e o número de micro-instruções que foram alocadas para alguns registradores físicos. E por fim, a coluna ldreg, que confere o percentual e o número de micro-instruções que são loads que foram alocadas tanto para um registrador fisíco como para fila de loads. Tabela 2 – Issue Dados Analisados Benchmark Exception no_fu Misspeculated Complete Branch-mispredict Replay 175.vpr 0,30% 3,20% 0,10% 90,40% 3,10% 2,90% 53 630 21 17567 612 564 0,30% 3,30% 0,10% 90,20% 3,10% 3,00% 51 643 20 17801 602 586 0,30% 3,30% 0,10% 90,20% 3,00% 3,10% 50 638 18 17535 588 594 0,30% 3,00% 0,10% 90,70% 3,10% 2,80% 50 582 19 17470 591 542 0,30% 3,50% 0,10% 89,80% 3,20% 3,10% 53 684 24 17704 625 608 0,40% 3,40% 0,10% 90,00% 3,10% 3,00% 69 658 27 17574 595 581 0,20% 3,30% 0,10% 90,30% 3,10% 3,00% 46 638 18 17636 608 590 0,40% 3,50% 0,10% 89,70% 3,10% 3,20% 78 696 25 17810 620 629 0,40% 3,40% 0,10% 89,80% 3,20% 3,10% 74 676 24 17867 630 625 256.bzip2 183.equake 188.ammp 433.milc 456.hmmer 458.sjeng 470.lbm 999.specrand uipc result 0.32627 19447 0.32633 19703 0.32252 19423 0.32229 19254 0.32602 19698 0.33061 19504 0.32316 19536 0.33692 19858 0.33631 19896 Na Tabela 2 mostra a estatística relacionada à emissão (ao Issue) e também foram retiradas após fazer um commit de 10000 intruções para cada benchmark executado. A linha de cima de cada das métricas para cada benchmark é a porcentagem, já a linha de baixo são os números de micro-instruções. Essas estatísticas compreendem todas as micro-instruções que foram emitidas. A segunda coluna, Exception, mostra o percentual de exceções geradas pelo processador de acordo com o número total de micro-instruções emitidas, já na linha de baixo o número de micro-instruções. Na terceira coluna, no_fu, é mostrado a porcentagem de microinstruções que tiveram que esperar para serem emitidas por falta de unidade funcional disponível. A coluna Misspeculated, é a taxa de miss de especulação das instruções, ou seja, todas as micro-instruções que vieram depois tiveram que ser descartadas. Na coluna Branchmispredict, mostra a taxa de miss na predição de desvios. A coluna Replay mostra o percentual e o número de micro-instruções que foram tentadas a executa, mas não foram completadas, então tiveram que voltar posições na fila de emissão. A coluna uipc mostra a quantidade de micro-intruções por ciclo de clock. E, por fim, a coluna result, o número total de microinstruções que foram executadas até esse clock. A Figura 2 mostra o gráfico das instruções que foram executadas com sucesso. O restante das instruções não foi executado devido a alguma dependência ou exceção geradas, conforme demonstrado na Tabela 1. 3 Consideração finais Esse artigo mostrou alguns experimentos utilizando a ferramenta PTLSim, que é um simulador com acurácia de ciclos e máquina virtual para arquitetura x86 e x86-64. Foi simulado a arquitetura K8 da AMD, utilizando um processador Turion X2. Os esperimentos foram feitos executando alguns benchmarks da classe SPEC2000 e SPEC2006 de inteiros e ponto-flutuante. Os resultados compreendem algumas métricas que foram escolhidas para serem coletadas e analisadas, como a taxa de branch-mispredict. Vale ressaltar que outros resultados foram obtidos e analisados, porém não inseridos nesse artigo. O PTLsim permite o projetista obter várias métricas e cabe a ele analisar as informações relevantes ao objetivo que pretende realizar com a simulação. Essas métricas permitem avaliar o comportamento do pipeline em nível de ciclo, demonstrando a importância de simuladores com acurácia de ciclos para a simulação de processadores. Referências bibliográficas AGNER, F. The microarchitecture of Intel, AMD and VIA CPUs: An optimization guide for assembly programmers and compiler makers. Copenhagen University College of Engineering, 2012. AMD – Advanced Micro Devices. Processador AMD Athlon 64. Disponível em: </br/pages/amdhomepage.aspx>. Acesso em: mai-2011. FREITAS, M. E. Arquiteturas Superescalares. Fundação CPqD. Centro de Pesquisa e Desenvolvimento em Telecomunicações, 2003. HOFFMAN, C, CAPISTRANO, B, GERMANO, D. Processadores AMD Athlon, Turion, Opteron e Phenom: características, evolução e arquitetura. Universidade Estadual de Campinas – UNICAMP, 2008. YOURST, Matt T. Ptlsim: A cycle accurate full system x86-64 microarchitectural simulator. Department of Computer Science. State University of New York at Binghamton. IEEExplore Digital Library, 2007. RODRIGUES, R. J. Computação de 64 bits. UCE/UFRJ, 2005. ROMANO, Gustavo. Arquitetura AMD Athlon 64. Instituto de Informática – Universidade Federal do Rio Grande do Sul (UFRGS), 2006. STOKES, J. H.. Inside amd’s hammer: the 64-bit architecture behind the opteron and athlon 64. Airs Technica, 2005.