É comum afirmar que a arquitetura do processador Itanium de 64 bits da Intel falhou porque o revolucionário conjunto de instruções EPIC era muito difícil de escrever para um bom compilador, o que significava a falta de boas ferramentas de desenvolvedor para IA64, o que significava a falta de desenvolvedores criando programas para a arquitetura e, portanto, ninguém queria usar hardware sem muito software para isso; portanto, a plataforma falhou e tudo por falta deuma unha em ferradura bons compiladores.
Mas por que o material do compilador era um problema técnico tão difícil? Parece-me que se o paralelismo explícito no EPIC era difícil para os fornecedores de compiladores implementarem ... por que colocar esse fardo sobre eles em primeiro lugar? Não é como se uma solução boa e bem compreendida para esse problema ainda não existisse: em vez disso, imponha essa carga à Intel e forneça aos escritores-compiladores um alvo mais simples.
O Itanium foi lançado em 1997. A essa altura, o sistema de bytecodes do Código P UCSD tinha quase 20 anos, a máquina Z apenas um pouco mais nova e a JVM era a nova estrela quente em ascensão no mundo das linguagens de programação. Existe alguma razão pela qual a Intel não especificou uma linguagem "simples Itanium bytecode" e forneceu uma ferramenta que converte esse bytecode em código EPIC otimizado, aproveitando seus conhecimentos como as pessoas que projetaram o sistema em primeiro lugar?
Respostas:
Pelo que me lembro na época, a questão não era apenas os detalhes do IA64, era a competição com o conjunto de instruções x86-64 da AMD. Ao tornar sua arquitetura compatível com o conjunto de instruções x86, a AMD conseguiu aproveitar as ferramentas e os conjuntos de habilidades de desenvolvedor existentes. A iniciativa da AMD foi tão bem-sucedida que a Intel (e a Via) foram essencialmente forçadas a adotar a arquitetura x86-64.
A grande barreira na época era de 4 GB de RAM em PCs desktop (mais realisticamente ~ 3,4 GB utilizáveis no Windows). O x86-64 quebrou essa barreira e abriu a computação de maior poder para todos. Se a AMD nunca tivesse lançado o x86-64, tenho certeza que a Intel ficaria feliz em ter todo mundo que quisesse pular para 4 GB de RAM + pagar um grande prêmio por anos por esse privilégio. Demonstrando a lentidão dos mercados, levou anos para que os aplicativos alcancem a programação multithread de 64 bits e, mesmo agora, 4 GB de RAM são padrão em PCs de gama baixa.
Em suma, a Intel tentou dar um salto revolucionário com a arquitetura IA64, e a AMD deu um passo evolutivo com o x86-64. Em um mercado estabelecido, as etapas evolutivas que permitem aos profissionais do conhecimento alavancar as habilidades existentes vencerão as etapas revolucionárias que exigem que todos aprendam novas habilidades. Independentemente das diferenças qualitativas entre as arquiteturas, o IA64 não conseguiu superar o momento de sua própria plataforma x86, uma vez que a AMD adicionou as extensões x86-64.
Não acredito que o IA64 fosse muito difícil de programar. Só foi difícil em relação às alternativas. O argumento de @ delnan sobre o IR de baixo nível está bem, mas acho que não faria diferença.
Por que a Intel não tentou arcar com esse ônus, quem sabe? Eles eram o poder do mercado na época. A AMD era uma ameaça, mas a Intel era o rei da colina. Talvez eles pensassem que o IA64 seria muito melhor do que qualquer outra coisa que eles pudessem mover o mercado inteiro. Talvez eles estivessem tentando criar uma camada premium e deixar a AMD, VIA etc. na segunda camada brigando por hardware comum de baixa margem - uma estratégia que a Intel e a Apple empregaram com bastante êxito.
Itanium foi uma tentativa deliberada de criar uma plataforma premium e retirar o tapete da AMD, VIA etc.? Claro, é assim que os negócios funcionam.
fonte
O artigo da Wikipedia sobre EPIC já descreveu os muitos perigos comuns ao VLIW e EPIC.
Se alguém não captar o senso de fatalismo desse artigo, deixe-me destacar isso:
Em outras palavras, qualquer projeto de hardware que não consiga lidar com (*) a latência não determinística do acesso à memória se tornará uma falha espetacular.
(*) Ao "lidar com", é necessário obter desempenho de execução razoavelmente bom (em outras palavras, "competitivo em termos de custo"), o que exige não deixar a CPU ficar ociosa por dezenas a centenas de ciclos com tanta frequência.
Observe que a estratégia de enfrentamento empregada pelo EPIC (mencionada no artigo da Wikipedia vinculado acima) não resolve o problema. Diz apenas que o ônus de indicar dependência de dados agora recai sobre o compilador. Isso é bom; o compilador já possui essas informações, portanto, é simples para ele cumprir. O problema é que a CPU ainda está ociosa por dezenas a centenas de ciclos em um acesso à memória. Em outras palavras, externaliza uma responsabilidade secundária, embora ainda não consiga lidar com a responsabilidade primária.
A questão pode ser reformulada como: "Dada uma plataforma de hardware destinada a ser uma falha, por que (1) não (2) os escritores do compilador não puderam fazer um esforço heróico para resgatá-la?"
Espero que minha reformulação torne a resposta a essa pergunta óbvia.
Há um segundo aspecto da falha que também é fatal.
As estratégias de enfrentamento (mencionadas no mesmo artigo) pressupõem que a pré-busca baseada em software possa ser usada para recuperar pelo menos parte da perda de desempenho devido à latência não determinística do acesso à memória.
Na realidade, a pré-busca só é lucrativa se você estiver executando operações de streaming (lendo a memória de maneira sequencial ou altamente previsível).
(Dito isto, se o seu código fizer acesso frequente a algumas áreas de memória localizada, o armazenamento em cache ajudará.)
No entanto, a maioria dos softwares de uso geral deve fazer muitos acessos aleatórios à memória. Se considerarmos os seguintes passos:
Para a maioria dos softwares de uso geral, esses três devem ser executados em rápida sucessão. Em outras palavras, nem sempre é possível (dentro dos limites da lógica do software) calcular o endereço antecipadamente ou encontrar trabalho suficiente para preencher as barracas entre essas três etapas.
Para ajudar a explicar por que nem sempre é possível encontrar trabalho suficiente para encher as bancas, eis como se pode visualizá-lo.
(*) Se pudéssemos
NOP
fazer um trabalho útil ...As CPUs modernas tentam lidar com o mesmo usando informações dinâmicas - rastreando simultaneamente o progresso de cada instrução à medida que circulam pelos pipelines. Como mencionei acima, parte dessas informações dinâmicas se deve à latência não determinística da memória, portanto, não pode ser prevista com precisão pelos compiladores. Em geral, simplesmente não há informações suficientes disponíveis no momento da compilação para tomar decisões que possam preencher essas barracas.
Em resposta à resposta de AProgrammer
Não é que "compilador ... extrair paralelismo seja difícil".
Reordenar a memória e as instruções aritméticas dos compiladores modernos é a evidência de que ele não tem nenhum problema em identificar operações que são independentes e, portanto, executáveis simultaneamente.
O principal problema é que a latência não determinística da memória significa que qualquer "emparelhamento de instruções" codificado para o processador VLIW / EPIC acabará sendo paralisado pelo acesso à memória.
A otimização de instruções que não paralisam (somente registro, aritmética) não ajudará nos problemas de desempenho causados por instruções com grande probabilidade de paralisação (acesso à memória).
É um exemplo de falha na aplicação da regra de otimização 80-20: A otimização de coisas que já são rápidas não melhorará significativamente o desempenho geral, a menos que as coisas mais lentas também estejam sendo otimizadas.
Em resposta a resposta por Basile Starynkevitch
Não é "... (seja o que for) difícil", é que o EPIC é inadequado para qualquer plataforma que precise lidar com alto dinamismo na latência.
Por exemplo, se um processador tiver todo o seguinte:
Então VLIW / EPIC será um bom ajuste.
Onde se encontra esses processadores? DSP. E é aqui que o VLIW floresceu.
Em retrospecto, o fracasso do Itanium (e o contínuo despejo dos esforços de P&D em um fracasso, apesar das evidências óbvias) é um exemplo de fracasso organizacional e merece ser estudado em profundidade.
É verdade que os outros empreendimentos do fornecedor, como hyperthreading, SIMD etc., parecem ter grande sucesso. É possível que o investimento no Itanium tenha tido um efeito enriquecedor nas habilidades de seus engenheiros, o que pode ter lhes permitido criar a próxima geração de tecnologia de sucesso.
fonte
TL; DR: 1 / há outros aspectos na falha do Itanium que não os problemas do compilador e podem muito bem ser suficientes para explicá-lo; 2 / um código de bytes não teria resolvido os problemas do compilador.
Bem, eles também estavam atrasados (planejado para 98, primeira remessa em 2001) e quando finalmente entregaram o hardware, nem tenho certeza de que ele entregou o que foi prometido para a data anterior (IIRC, eles pelo menos abandonaram parte do emulação x86 que foi planejada inicialmente), então não tenho certeza de que, mesmo que os problemas de compilação tenham sido resolvidos (e o AFAIK, ainda não), eles teriam êxito. O aspecto do compilador não era o único aspecto excessivamente ambicioso.
Não sei onde você coloca a ferramenta.
Se estiver no processador, você possui apenas outra microarquitetura e não há razão para não usar o x86 como ISA público (pelo menos para a Intel, a incompatibilidade tem um custo maior do que o que poderia trazer um ISA público mais limpo).
Se for externo, iniciar a partir de um código de bytes torna ainda mais difícil do que iniciar a partir de um idioma de nível superior. O problema com o EPIC é que ele pode usar apenas o paralelismo que um compilador pode encontrar e extrair esse paralelismo é difícil. Conhecer as regras de idioma oferece mais possibilidades do que se você estiver limitado por algo já agendado. Minha (admitida não confiável e de alguém que seguiu isso de longe) é que o que a HP (*) e a Intel não conseguiram alcançar na frente do compilador é a extração do paralelismo no nível de idioma, não o baixo nível que estaria presente em um byte código.
Talvez você esteja subestimando o custo pelo qual o processador atual alcança seu desempenho. OOO é mais eficaz que as outras possibilidades, mas certamente não é eficiente. A EPIC queria usar o orçamento da área usado pela implementação do OOO para fornecer mais computação bruta, esperando que os compiladores pudessem fazer uso dela. Como descrito acima, não apenas ainda somos incapazes - como o AFAIK, mesmo em teoria - de escrever compiladores com essa capacidade, mas o Itanium possui outras características difíceis de implementar que chegaram atrasadas e seu poder bruto não era suficiente. até competitivo (exceto talvez em alguns nichos de mercado com muita computação FP) com o outro processador de ponta quando saiu da fábrica.
(*) Você também parece subestimar o papel da HP no EPIC.
fonte
Algumas coisas.
A IPF estava em ordem, por um lado. Isso significava que você não podia confiar na reordenação para salvá-lo no caso de uma falta de cache ou outro evento de longa duração. Como resultado, você acabou precisando confiar em recursos especulativos - ou seja, cargas especulativas (cargas que foram autorizadas a falhar - úteis se você não sabia se precisaria de um resultado de carga) e cargas avançadas (cargas que poderiam ser execute novamente, usando o código de recuperação, se ocorrer um risco.) Fazer as coisas direito era difícil, principalmente com cargas avançadas! Havia também dicas de pré-busca de ramificação e cache que realmente só podiam ser usadas de forma inteligente por um programador de montagem ou usando a otimização guiada por perfil, geralmente não com um compilador tradicional.
Outras máquinas na época - o UltraSPARC - estavam em ordem, mas a IPF também teve outras considerações. Um estava codificando o espaço. As instruções do Itanium não eram, por natureza, especialmente densas - um pacote configurável de 128 bits continha três operações e um campo de modelo de 5 bits, que descrevia as operações no pacote configurável e se todas elas podiam ser emitidas juntas. Isso resultou em um tamanho efetivo de operação de 42,6 bits - compare com 32 bits na maioria das operações dos RISCs comerciais da época. (Isso foi antes do Thumb2, et al. - o RISC ainda significava rigidez de comprimento fixo.) Pior ainda, você nem sempre tinha ILP suficiente para caber no modelo que estava usando - então você teria que usar o NOP-pad para preencher o modelo ou pacote. Isso, combinado com a baixa densidade relativa existente, significava que obter uma taxa decente de acertos do cache i era a) realmente importante,
Embora eu sempre tenha achado que o argumento "o compilador era o único problema" era exagerado - havia problemas microarquiteturais legítimos que realmente não favoreciam o código de uso geral - não foi especialmente divertido gerar código para comparação para as máquinas OoO mais estreitas e com maior frequência do dia. Quando você realmente podia preenchê-lo adequadamente, o que geralmente envolvia PGO ou codificação manual, foi ótimo - mas na maioria das vezes, o desempenho dos compiladores era realmente pouco inspirador. A IPF não facilitou a geração de ótimos códigos e foi implacável quando o código não era ótimo.
fonte
O que você descreve é um pouco o que a Transmeta tentou fazer com o software de transformação de código (que estava traduzindo dinamicamente x86 "bytecode" para o código interno da máquina da Transmeta).
Quanto ao por que a Intel não conseguiu fazer um bom compilador suficiente para IA64 ... eu acho é que eles não têm o suficiente conhecimento do compilador em casa (mesmo se é claro que eles tinham alguns muito bons especialistas do compilador dentro, mas provavelmente não o suficiente para faça uma massa crítica). Eu acho que o gerenciamento deles subestimou os esforços necessários para criar um compilador.
AFAIK, Intel EPIC falhou porque a compilação para EPIC é realmente difícil, e também porque quando a tecnologia do compilador melhorou lenta e gradualmente, outros concorrentes também foram capazes de melhorar seu compilador (por exemplo, para AMD64), compartilhando algum conhecimento sobre compiladores.
BTW, eu desejava que o AMD64 tivesse sido mais um conjunto de instruções RISCy. Poderia ter sido um POWERPC64 (mas provavelmente não foi por causa de problemas de patente, por causa das demandas da Microsoft na época, etc ...). A arquitetura do conjunto de instruções x86-64 não é realmente uma arquitetura "muito boa" para o gravador de compilador (mas, de alguma forma, é "suficientemente boa").
Além disso, a arquitetura IA64 incorporou algumas fortes limitações, por exemplo, as 3 instruções / palavra foram boas, desde que o processador tivesse 3 unidades funcionais para processá-las, mas uma vez que a Intel foi para os chips IA64 mais novos, eles adicionaram mais unidades funcionais e as instruções paralelismo de nível foi novamente difícil de alcançar.
Talvez o RISC-V (que é um ISA de código aberto) tenha gradualmente sucesso suficiente para torná-lo competitivo para outros processadores.
fonte
Como Robert Munn apontou - foi a falta de compatibilidade com versões anteriores que matou o Itanium (e muitas outras "novas" tecnologias).
Enquanto escrever um novo compilador pode ter sido difícil, você precisa apenas de alguns deles. O compilador CA que produz código otimizado é essencial - caso contrário, você não terá um sistema operacional utilizável. Você precisa de um compilador C ++, Java e, como a principal base de usuários seria o Windows, algum tipo de Visual Basic. Portanto, isso não era realmente um problema. Havia um sistema operacional decente (NT) e um bom compilador C disponível.
O que pareceria um esforço trivial para uma empresa que oferece um produto de software - recompile e teste novamente sua base de código C (e na época a maioria teria sido escrita em C puro!) Não era tão simples; a conversão de um grande conjunto de programas C que assumiu um número inteiro de 32 bits e assumiu o endereçamento de 32 bits em uma arquitetura nativa de 64 bits estava cheia de armadilhas. Se o IA64 tivesse se tornado um chip dominante (ou mesmo popular)! A maioria das empresas de software teria mordido a bala e feito o esforço.
Um chip tão rápido com um sistema operacional razoável, mas um conjunto muito limitado de software disponível; portanto, poucas pessoas o compraram; portanto, poucas empresas de software forneceram produtos para ele.
fonte
O que matou o Itanium foram os atrasos nas remessas que abriram as portas para o AMD64 entrar antes que os fornecedores de software se comprometessem a migrar para o IA64 para aplicativos de 64 bits.
Deixar a otimização para o compilador foi uma boa ideia. Muita coisa pode ser feita estática que, de outra forma, é ineficiente em hardware. Os compiladores se tornaram muito bons nisso, especialmente ao usar o perfil PGO (eu trabalhei na HP e o compilador da HP tendia a superar os da Intel). O PGO foi difícil de vender, no entanto, é um processo difícil para o código de produção.
O IPF deveria ser compatível com versões anteriores, mas, uma vez que o AMD64 foi lançado, tornou-se discutível, a batalha foi perdida e acredito que o hardware X86 na CPU foi retirado para redirecionar como uma CPU de servidor. Itanium como arquitetura não era ruim, as 3 instruções por palavra não eram um problema. O que foi um problema foi a implementação do hyperthreading, ao trocar pilhas durante a memória de E / S, era muito lenta (para esvaziar e recarregar o pipeline) até Montecito etc., o que a impediu de competir com CPUs PowerPC fora de ordem. Os compiladores tiveram que corrigir tardiamente para detectar falhas nas implementações de CPU, e parte da margem de desempenho foi perdida com dificuldade em prever erros.
A arquitetura permitiu que o Itanium fosse relativamente simples, fornecendo ferramentas para o compilador obter desempenho a partir dele. Se a plataforma tivesse sobrevivido, as CPUs teriam se tornado mais complexas e eventualmente encadeadas, fora de ordem, etc., como x86. No entanto, os primeiros transistores concentrados em gens contam com outros esquemas de desempenho desde que o compilador lidou com muitas coisas difíceis.
A plataforma IPF apostou no compilador e nas ferramentas e foi a primeira arquitetura a expor um design extremamente completo e poderoso da Unidade de Monitoramento de Desempenho (PMU), que mais tarde foi transportado para o Intel x86. Assim, os desenvolvedores de ferramentas poderosos ainda não a utilizam em sua capacidade total de criar um perfil do código.
Se você observar os sucessos da ISA, muitas vezes não é o lado técnico que lança os dados. É o seu lugar no tempo e nas forças do mercado. Veja o SGI Mips, o DEC Alpha ... O Itanium acabou de ser suportado pelos servidores perdedores, SGI e HP, empresas com gerências que se concentraram em erros estratégicos de negócios. A Microsoft nunca entrou em cena e adotou o AMD64 para não ser encaixotado, apenas com a Intel como player, e a Intel não jogou bem com a AMD para lhes dar uma maneira de viver no ecossistema, pois pretendiam exterminar a AMD.
Se você olhar para onde estamos hoje, o complexo hardware do X86 levou a um beco sem saída da evolução até agora. Estamos presos a 3 + GHz e despejando núcleos com pouco uso para isso. O design mais simples do Itanium teria empurrado mais coisas para o compilador (espaço para crescimento), permitindo a construção de tubulações mais finas e rápidas. Com a mesma geração e tecnologia fabulosa, ele estaria funcionando mais rápido e limitado do mesmo modo, mas um pouco mais alto, com talvez outras portas para abrir para pressionar a lei de Moore.
Bem, pelo menos, o acima é minhas crenças :)
fonte
A memória está ficando vaga ... O Itanium teve ótimas idéias que precisariam de grande suporte do compilador. O problema era que não era um recurso, eram muitos. Cada um não era grande coisa, todos juntos eram.
Por exemplo, havia um recurso de loop em que uma iteração do loop operaria em registros de diferentes iterações. O x86 lida com o mesmo problema através de uma enorme capacidade fora de ordem.
Naquela época, Java e JVMs estavam na moda. O que a IBM disse foi que, com o PowerPC, era possível compilar o bytecode rapidamente e a CPU o tornaria rápido. Não no Itanium.
fonte