Começando com o Pentium Pro (microarquitetura P6), a Intel redesenhou seus microprocessadores e usou o núcleo RISC interno de acordo com as antigas instruções CISC. Desde o Pentium Pro, todas as instruções CISC são divididas em partes menores (uops) e depois executadas pelo núcleo RISC.
No início, ficou claro para mim que a Intel decidiu ocultar uma nova arquitetura interna e forçar os programadores a usar o "shell CISC". Graças a esta decisão, a Intel pode redesenhar totalmente a arquitetura dos microprocessadores sem quebrar a compatibilidade, é razoável.
No entanto, eu não entendo uma coisa, por que a Intel ainda mantém um conjunto de instruções RISC interno escondido por tantos anos? Por que eles não permitem que os programadores usem instruções RISC como o antigo conjunto de instruções CISC x86?
Se a Intel mantém a compatibilidade com versões anteriores por tanto tempo (ainda temos o modo 8086 virtual próximo ao modo de 64 bits), por que eles não nos permitem compilar programas para que eles ignorem as instruções CISC e usem o núcleo RISC diretamente? Isso abrirá um caminho natural para abandonar lentamente o conjunto de instruções x86, que está obsoleto hoje em dia (esta é a principal razão pela qual a Intel decidiu usar o núcleo RISC dentro, certo?).
Olhando para a nova série Intel 'Core i', vejo que eles apenas estendem o conjunto de instruções CISC adicionando AVX, SSE4 e outros.
fonte
Respostas:
Não, o conjunto de instruções x86 certamente não está obsoleto. É tão popular como sempre. O motivo pelo qual a Intel usa um conjunto de microinstruções semelhantes a RISC internamente é porque eles podem ser processados com mais eficiência.
Portanto, uma CPU x86 funciona tendo um decodificador bem pesado no front-end, que aceita instruções x86 e as converte em um formato interno otimizado, que o back-end pode processar.
Quanto à exposição desse formato a programas "externos", existem dois pontos:
Este não é um arranjo exatamente perfeito, mas o custo é bastante pequeno e é uma escolha muito melhor do que projetar a CPU para suportar dois conjuntos de instruções completamente diferentes. (Nesse caso, eles provavelmente acabariam inventando um terceiro conjunto de micro-operações para uso interno, só porque eles podem ser ajustados livremente para melhor se adequar à arquitetura interna da CPU)
fonte
A verdadeira resposta é simples.
O principal fator por trás da implementação dos processadores RISC foi reduzir a complexidade e ganhar velocidade. A desvantagem do RISC é a densidade de instrução reduzida, o que significa que o mesmo código expresso em formato semelhante ao RISC precisa de mais instruções do que o código CISC equivalente.
Este efeito colateral não significa muito se sua CPU funcionar na mesma velocidade que a memória, ou pelo menos se ambos rodarem em velocidades razoavelmente semelhantes.
Atualmente a velocidade da memória em comparação com a velocidade do CPU mostra uma grande diferença nos clocks. As CPUs atuais às vezes são cinco vezes ou mais mais rápidas do que a memória principal.
Esse estado da tecnologia favorece um código mais denso, algo que o CISC oferece.
Você pode argumentar que os caches podem acelerar CPUs RISC. Mas o mesmo pode ser dito sobre cpus CISC.
Você obtém uma melhoria de velocidade maior usando CISC e caches do que RISC e caches, porque o mesmo tamanho de cache tem mais efeito no código de alta densidade que o CISC fornece.
Outro efeito colateral é que o RISC é mais difícil na implementação do compilador. É mais fácil otimizar compiladores para cpus CISC. etc.
A Intel sabe o que está fazendo.
Isso é tão verdade que o ARM tem um modo de densidade de código mais alto chamado Thumb.
fonte
Você precisa olhar para o ângulo de negócios disso. A Intel, na verdade, tentou deixar o x86, mas é a galinha dos ovos de ouro para a empresa. O XScale e o Itanium nunca chegaram nem perto do nível de sucesso que seu principal negócio x86 tem.
O que você está basicamente pedindo é que a Intel corte seus pulsos em troca de fuzzies calorosos dos desenvolvedores. Minar o x86 não é do interesse deles. Qualquer coisa que faça com que mais desenvolvedores não tenham que escolher como alvo o x86 prejudica o x86. Isso, por sua vez, os enfraquece.
fonte
A resposta é simples. A Intel não está desenvolvendo CPUs para desenvolvedores ! Eles estão desenvolvendo-os para as pessoas que fazem a compra decisões de , o que, aliás, é o que todas as empresas no mundo fazem!
A Intel há muito tempo se comprometeu a que, (dentro do razoável, é claro), suas CPUs permaneceriam compatíveis com as versões anteriores. As pessoas querem saber que, quando compram um novo computador baseado em Intel, tudo seus softwares atuais rodarão exatamente da mesma forma que em seus computadores antigos. (Embora, esperançosamente, mais rápido!)
Além disso, a Intel sabe exatamente o quão importante é esse compromisso, porque uma vez eles tentaram seguir um caminho diferente. Exatamente quantas pessoas você conhece com uma CPU Itanium?!?
Você pode não gostar, mas aquela decisão, de ficar com o x86, é o que tornou a Intel um dos nomes de negócios mais reconhecidos do mundo!
fonte
A resposta de @jalf cobre a maioria dos motivos, mas há um detalhe interessante que ele não menciona: o núcleo interno semelhante ao RISC não foi projetado para executar um conjunto de instruções como ARM / PPC / MIPS. O imposto x86 não é pago apenas nos decodificadores que consomem muita energia, mas até certo ponto em todo o núcleo. ou seja, não é apenas a codificação da instrução x86; é cada instrução com uma semântica estranha.
Vamos fingir que a Intel criou um modo operacional em que o fluxo de instruções era diferente de x86, com instruções mapeadas mais diretamente para uops. Vamos também fingir que cada modelo de CPU tem seu próprio ISA para este modo, então eles ainda estão livres para alterar os internos quando quiserem e expô-los com uma quantidade mínima de transistores para decodificação de instruções deste formato alternativo.
Presumivelmente, você ainda teria apenas o mesmo número de registros, mapeados para o estado arquitetônico x86, de modo que os sistemas operacionais x86 podem salvá-lo / restaurá-lo em alternâncias de contexto sem usar o conjunto de instruções específico da CPU. Mas se descartarmos essa limitação prática, sim, poderíamos ter mais alguns registros porque podemos usar os registros temporários ocultos normalmente reservados para o microcódigo 1 .
Se apenas tivermos decodificadores alternativos sem alterações nos estágios posteriores do pipeline (unidades de execução), este ISA ainda terá muitas excentricidades x86. Não seria uma arquitetura RISC muito boa. Nenhuma instrução seria muito complexa, mas algumas das outras loucuras do x86 ainda estariam lá.
Por exemplo: os deslocamentos para a esquerda / direita deixam o sinalizador de estouro indefinido, a menos que a contagem de deslocamento seja um, caso em que OF = a detecção usual de estouro com sinal. Loucura semelhante para gira. No entanto, as instruções RISC expostas podem fornecer mudanças sem sinalizador e assim por diante (permitindo o uso de apenas um ou dois dos vários uops que geralmente entram em algumas instruções x86 complexas). Portanto, isso realmente não se sustenta como o principal contra-argumento.
Se você for fazer um decodificador totalmente novo para um ISA RISC, poderá fazer com que ele selecione partes das instruções x86 para serem expostas como instruções RISC. Isso atenua um pouco a especialização x86 do núcleo.
A codificação da instrução provavelmente não seria de tamanho fixo, uma vez que uops individuais podem conter muitos dados. Muito mais dados do que faz sentido se todos os insns forem do mesmo tamanho. Um único uop micro-fundido pode adicionar um operando imediato de 32 bits e um operando de memória que usa um modo de endereçamento com 2 registradores e um deslocamento de 32 bits. (No SnB e posterior, apenas os modos de endereçamento de registro único podem microfundir com operações de ALU).
uops são muito grandes e não muito semelhantes às instruções ARM de largura fixa. Um conjunto de instruções de 32 bits de largura fixa só pode carregar imediatos de 16 bits por vez, portanto, o carregamento de um endereço de 32 bits requer um par de carga imediata baixa-metade / carga alta-imediata. O x86 não precisa fazer isso, o que o ajuda a não ser terrível, com apenas 15 registros GP limitando a capacidade de manter constantes nos registros. (15 é uma grande ajuda sobre 7 registros, mas dobrar novamente para 31 ajuda muito menos, eu acho que alguma simulação encontrada. RSP geralmente não é de uso geral, então é mais como 15 registros GP e uma pilha.)
TL; Resumo DR:
De qualquer forma, essa resposta se resume a "o conjunto de instruções x86 é provavelmente a melhor maneira de programar uma CPU que deve ser capaz de executar instruções x86 rapidamente", mas espero que esclareça as razões.
Formatos uop internos no front-end vs. back-end
Veja também Micro fusão e modos de endereçamento para um caso de diferenças no que os formatos uop front-end vs. back-end podem representar nas CPUs Intel.
Nota de rodapé 1 : Existem alguns registros "ocultos" para uso como temporários por microcódigo. Esses registradores são renomeados da mesma forma que os registradores de arquitetura x86, de modo que as instruções multi-uop podem ser executadas fora de ordem.
por exemplo,
xchg eax, ecx
em CPUs da Intel decodifica como 3 uops ( por quê? ), e nosso melhor palpite é que esses uops do tipo MOV o fazemtmp = eax; ecx=eax ; eax=tmp;
. Nessa ordem, porque eu meço a latência da direção dst-> src em ~ 1 ciclo, vs. 2 para o outro lado. E esses movimentos não são normaismov
instruções ; eles não parecem ser candidatos para eliminação de movimento de latência zero.Veja também http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/ para uma menção de tentar medir experimentalmente o tamanho do PRF e ter que levar em conta os registros físicos usados para manter o estado arquitetônico, incluindo registros ocultos.
No front-end após os decodificadores, mas antes do estágio de emissão / renomeação que renomeia os registros no arquivo de registro físico, o formato uop interno usa números de registro semelhantes aos números de registro x86, mas com espaço para lidar com esses registros ocultos.
O formato uop é um pouco diferente dentro do núcleo fora de ordem (ROB e RS), também conhecido como back-end (após o estágio de emissão / renomeação). Cada um dos arquivos de registro físico int / FP tem 168 entradas em Haswell , então cada campo de registro em um uop precisa ser largo o suficiente para lidar com esse número.
Como o renomeador está no HW, provavelmente seria melhor usá-lo, em vez de alimentar instruções programadas estaticamente diretamente no back-end. Portanto, trabalharíamos com um conjunto de registros tão grande quanto os registros de arquitetura x86 + temporários de microcódigo, não mais do que isso.
O back-end foi projetado para funcionar com um renomeador de front-end que evita os riscos WAW / WAR, portanto, não poderíamos usá-lo como uma CPU em ordem, mesmo se quiséssemos. Ele não tem intertravamentos para detectar essas dependências; que é tratado por emitir / renomear.
Seria ótimo se pudéssemos alimentar uops no back-end sem o gargalo do estágio de edição / renomeação (o ponto mais estreito nos pipelines modernos da Intel, por exemplo, 4-wide no Skylake vs. 4 ALU + 2 load + 1 store ports em o back-end). Mas se você fez isso, não acho que você pode agendar código estaticamente para evitar a reutilização de registro e pisar em um resultado que ainda é necessário se uma falha de cache paralisar uma carga por um longo tempo.
Portanto, praticamente precisamos alimentar o uops para o estágio de emissão / renomeação, provavelmente ignorando a decodificação, não o cache uop ou IDQ. Então, obtemos exec normal OoO com detecção sã de perigo. A tabela de alocação de registro é projetada apenas para renomear 16 + alguns registros inteiros no PRF inteiro de 168 entradas. Não podemos esperar que o HW renomeie um conjunto maior de registros lógicos no mesmo número de registros físicos; isso exigiria um RAT maior.
fonte
Além das respostas anteriores, o outro motivo é a segmentação de mercado. Acredita-se que algumas instruções sejam implementadas em microcódigo em vez de hardware, portanto, permitir que qualquer pessoa execute microoperações arbitrárias pode prejudicar a venda de novos cpus com "novas" instruções CISC de maior desempenho.
fonte
SHL r/m32, cl
tem uma dependência de entrada em FLAGS e decodifica para 3 uops no Skylake. No entanto, foi apenas 1 uop no Core2 / Nehalem, de acordo com os testes de Agner Fog.)