Por que a maioria dos sistemas RISC implementa a arquitetura de carga/armazém?
Dois conceitos entram em jogo aqui:
<- Ortogonalidade<
- Minimalismo
Ortogonalidade significa que você pode combinar operações com o mínimo de restrições. Por exemplo, suponha que o balde A contenha "modos de endereçamento operand" e o balde B contenha "operações matemáticas". Uma arquitetura totalmente ortogonal permitiria combinar qualquer modo de endereçamento de operando do balde A com qualquer operação matemática do balde B.
Minimalismo, especialmente no contexto de uma arquitetura RISC, significa quebrar operações em suas peças fundamentais de uma forma que permita que elas sejam combinadas da forma que você desejar. O objetivo é ter um número mínimo* de peças que possam ser combinadas em todas as operações que você possa imaginar. As peças devem ser suficientemente simples para requerer apenas 1 ciclo de execução no pipeline. Se você precisar adicionar dois números, se possível você gostaria de se limitar às formas fundamentais em que você pode adicionar dois números, sem considerar de onde vêm os operandos.
Nota: Se você examinar MIPS, SPARC, ARM e outros processadores RISC / RISC-like, você descobrirá que não há necessariamente um consenso sobre o que constitui um conjunto fundamental de operações. Por exemplo, você precisa de uma adição separada, assinada e não assinada? Diferentes larguras de palavras? No final, se o conseguir fazer num único ciclo, poderá obter um passe...
Em qualquer caso, isto levou à ideia de separar os acessos à memória dos cálculos. Ele permite que você mantenha a ortogonalidade enquanto ainda alcança o minimalismo.
Em máquinas CISC, você encontrará uma mistura de instruções de memorização-registo, registro-memória e registro-registo. Por exemplo, em x86, eu posso fazer um ADD entre um valor em memória e um valor em um registro, escrevendo o resultado de volta à memória. Ou eu posso adicionar dois valores em registros, escrevendo o resultado em um registro. Ou, posso adicionar um registo com um valor na memória, escrevendo o resultado de volta a um registo. Se você quiser fazer tal máquina ortogonal, você agora termina com instruções para cada combinação de modo de endereçamento cruzado com cada tipo de computação que você suporta.
Em uma arquitetura tipo RISC Load/Store, o acesso à memória é levado em consideração para suas próprias instruções. Então, ao invés de precisar de instruções [matemática]O(\mbox{modes} {mode} \mbox{operations})[/math] para alcançar a ortogonalidade total, você só precisa de instruções [matemática]O(\mbox{modes} + \mbox{operations})[/math])[/math.
Sua instrução cai de pressão de quadrática para linear. Isso torna muito mais fácil alcançar a ortogonalidade real.
Carregar/loja tem um benefício adicional: os acessos à memória são caros. Eles têm frequentemente latências grandes e imprevisíveis. O cálculo dos acessos à memória a partir do cálculo regular facilita a programação dos acessos à memória independentemente das instruções que dependem deles. Essa é uma grande parte da razão pela qual as arquiteturas CISC vão quebrar as instruções CISC em µops do tipo RISC sob o capô: Isso facilita o manuseio dos efeitos do sistema de memória.
As primeiras arquiteturas RISC não aproveitavam isso como as máquinas modernas fazem. As primeiras arquitecturas RISC pensavam que expor a latência de uma leitura de memória era uma boa ideia, e assim introduziram o mundo à ideia de uma ranhura de atraso de carga. Infelizmente, esse conceito não se dimensiona quando é preciso mudar o pipeline. Se você está fazendo processadores embutidos para os quais você está feliz em agendar estaticamente instruções, você pode se safar com isso. (Eu fiz por cerca de 20 anos.) Não funciona realmente para processadores mainstream que têm que rodar binários para código que você não pode recompilar.
Arquiteturas modernas do tipo RISC/RISC apenas rodam com a vantagem inerente de que o acesso à memória é dividido a partir do cálculo, e usam várias técnicas de scoreboarding para agendar dinamicamente instruções no pipeline quando seus argumentos estão disponíveis.
Um pensamento final: Hoje em dia, considero que RISC e CISC são mais rótulos de marketing do que qualquer tipo de classificação rigorosa. Há muitas máquinas que afirmam ser RISC que não se parecem nada com o minimalismo do MIPS R2000. Por outro lado, as práticas máquinas CISC modernas optimizam o seu subconjunto mais parecido com o RISC, tornando mais fácil de partir instruções em peças parecidas com RISC para correr na micro-arquitectura subjacente.
* OK, não absolutamente mínimo. Há um limite prático. Você poderia reduzir tudo para NANDs no limite, mas não o fará se você estiver construindo um processador prático. Em algum momento, cortar os estágios do seu pipeline ainda mais estreitos faz com que as operações comuns, em série, de caminhos críticos levem mais ciclos de relógio e mais tempo de relógio de parede.
Na prática, parece que uma adição inteira no tamanho da palavra da máquina parece ser o limite, pelo menos nos processadores em que eu trabalhei. Se você está nisso ou abaixo disso, você é bom. Se você estiver acima disso, você é cortado em múltiplos ciclos ou múltiplas operações. Porquê? Porque a acumulação (foo += barra) é extremamente comum, e fazer essa operação levar múltiplos ciclos faria explodir a contagem de ciclos de muitas coisas.
Isso significa que máquinas práticas com a marca RISC não são tão "Reduzidas" como a sigla implica. Como eu disse, é mais uma etiqueta de marketing do que uma classificação de engenharia rigorosa.
Artigos semelhantes
- Você implementa primeiro a parte da frente ou a parte de trás? Quando você implementa a IU?
- Qual é a diferença entre a arquitetura ARM e o RISC regular?
- Um Samsung Galaxy Tab S6 Lite pode ser usado em estudos de arquitetura por estudantes de arquitetura?
- A maioria dos carros tem sistemas de navegação por GPS. Se souber o número de identificação do veículo, pode seguir o seu percurso?