Por que não temos mais registros em microprocessadores?


18

Teoricamente, os registros não são necessários; todos os microprocessadores ainda funcionariam sem registros. Mas essa adição aparentemente trivial ajudou a tornar os microprocessadores mais eficientes.

Por que não podemos ter mais registros para extrair mais benefícios deles? Eles são apenas memória no chip e pode-se imaginar não muito difícil de adicionar? Que fator influenciou o número de registros para ser o que são agora e não, digamos, 10x mais?


8
@ Alper91 Muitas arquiteturas, hipotéticas e reais, não possuem registros, e isso não é de todo necessário. É simplesmente uma otimização útil.
pipe

4
Hmm. Ninguém mencionou o Sparc. A maior implementação poderia ter 520 registros (32 janelas vezes 16 registros, + 8 globais). Eu lembro deles.
9136

13
Eu acho que o número de bits na instrução que você precisa especificar no registro é um grande problema. Se você possui 1024 registros, precisará de pelo menos 30 bits para cada instrução aritmética - a menos que adicione outras restrições como "todos os 3 registros devem ser do mesmo grupo de 32 (nesse caso, você precisa de 20 bits).
user253751

8
@pipe - na verdade, praticamente qualquer projeto prático requer "registradores" no sentido esquemático, pois mesmo que você construa uma máquina de empilhamento ou algo assim, você precisa ter um local para armazenar os argumentos da ALU, ou as saídas - a maioria das memórias não tem três portas de acesso. E uma máquina de empilhar precisa de um ponteiro de empilhamento que é ... um registro! E não vamos mencionar os registros de pipeline. Você pode ocultar o uso desses "registradores" do programador, mas ainda precisa de alguns, e provavelmente quase tantos quanto uma máquina de registradores primitiva possui.
Chris Stratton

4
@ChrisStratton Claro, mas desde que não sejam expostos pelo ISA, é simplesmente um detalhe de implementação. Argumento um tanto inútil, pois não sabemos o que OP significa por registro .
pipe

Respostas:


33

Existem vários fatores:

  • microarquiteturas de alto desempenho usam renomeação de registros. Ou seja, o número de registros físicos é maior que o número de registros arquiteturalmente visíveis e eles são capazes de rastrear usos independentes deles.

  • dobrar o número de registros não duplica o desempenho. O ISTR (da arquitetura de computadores, Uma abordagem quantitativa ) que passa de 16 para 32 registradores traz algo como uma melhoria de 10%, assumindo que o aumento não tenha efeito adverso (que é uma suposição muito otimista).

  • registros arquitetonicamente visíveis têm custos. Por exemplo:

    • Aumentar seu número aumenta o número de bits obtidos no formato de instrução para indicar em qual registro está sendo acionado (dobrar o número de registros implica em ter mais um bit por registro no formato, impedindo o uso desses bits para outros usos ou forçar um tamanho de instrução mais longo).
    • Aumentar o número de registros de arquitetura aumenta o custo de alternância de contexto (pois eles devem ser salvos e restaurados na alternância de contexto).

1
Eu apostaria que a melhoria de desempenho de 16 a 32 registros depende totalmente do potencial de otimização do compilador em questão. No assembler, ter acesso ao dobro do número de registros (na arquitetura x64) pode melhorar muito o desempenho - mas apenas para funções de nicho e somente se elas forem realmente usadas.
Rdtsc 09/09/19

6
@rdtsc: passar de 8 para 16 registros de arquitetura oferece grandes melhorias na quantidade de derramamentos / recarregamentos de códigos típicos, de acordo com dados de simulações em um artigo vinculado a esta resposta . Isso afeta o tamanho do código, a contagem de instruções e a importância do encaminhamento de armazenamento de baixa latência. 16-> 32 é um efeito muito menor. O AFAICT, 16 registros de arquitetura é uma boa opção para hardware com renomeação de registro para remover os riscos WAR e WAW.
Peter Cordes

2
No entanto, o AVX512 da Intel adiciona mais 16 registros vetoriais, totalizando 32. (Além de duplicar sua largura para 64 bytes, uma linha de cache completa). Ocultar a latência de operações FP de alta latência e alta taxa de transferência pode levar muitos registros. por exemplo, a Intel Haswell possui 5c de lat, um por 0,5c de taxa de transferência de FMA, portanto, você precisa de 10 acumuladores de vetor para saturar as unidades de execução de FMA por uma redução (por exemplo, produto escalar ou somar uma matriz, em que a FMA faz parte de uma dependência transportada por loop ) x86-64 possui apenas 16 regs vetoriais. Mas lembre-se, operações inteiras, esp. nos registros GP, raramente têm mais de 1c de latência.
Peter Cordes

1
O trade-off é diferente para registros inteiros, FP e vetores. Por exemplo, salvar / restaurar lentamente registros inteiros não faz sentido, fazê-lo para o vetor um é uma aposta muito melhor. E o vetor ISA geralmente possui mais registros do que o número inteiro (o AltiVec tem pelo menos até 128, o ISTR leu cerca de 256 no Sparc, mas não consegue encontrar uma referência agora).
AProgrammer 9/09/16

1
en.wikipedia.org/wiki/AltiVec possui trinta e dois regs vetoriais 128b. Fiquei curioso sobre o SPARC e procurei como as coisas da janela de registro funcionavam para as alternâncias de contexto. Possui 32 registros visíveis ao mesmo tempo, mas usa uma janela deslizante em um arquivo de registro maior. Parece que nesta versão simplificada o sistema operacional precisa saber o tamanho de todo o arquivo de registro da janela deslizante para salvá-lo / restaurá-lo, porque mesmo que as instruções de deslizamento da janela forneçam memória para salvar / restaurar registros, se necessário, isso é feito capturando para o sistema operacional.
11266 Peter Cordes

16

Embora os registros e a RAM sejam ambos memória, eles são acessados ​​de maneiras diferentes, para refletir o custo (na área de chip ou de ciclos de clock ocultos) de acessá-los.

Os registros estão fortemente vinculados à ALU e podem assumir muitas funções de fontes de dados, coletores, modificadores etc. Portanto, eles precisam de uma grande variedade de conexões multiplexadas. Em algumas arquiteturas, podemos escrever R1 <= R2 + R3, e é exatamente isso que acontece em um único ciclo de clock. Cada registro é endereçado diretamente no código operacional, esse endereçamento é um recurso muito limitado.

Como os registros são caros de implementar, o número geralmente é limitado à ordem de 10/20 na maioria das arquiteturas.

A RAM está fracamente ligada à CPU, geralmente sendo canalizada através de uma única conexão compartilhada. Isso torna muito mais barato implementar uma grande quantidade de RAM. Os endereços de RAM geralmente vêm de um endereço armazenado em um registro, portanto, não consuma uma largura significativa de instruções.

O SPARC é uma arquitetura interessante, com registros de 72 a 640 de 64 bits, com um contexto de 32 registros que pode ser alterado com sobreposições para chamadas rápidas de sub-rotina com passagem de parâmetros. Você costuma não encontrá-los em PCs e servidores onde os custos importam, como em 99,999% dos aplicativos.


4
Outro aspecto é que você precisa salvar / restaurar registros durante uma alternância de contexto. Mais registros, mais tempo.
Michel Billaud

Gostaria de observar que o velho TMS9900 mantidos todos os registos seu trabalho na memória externa en.wikipedia.org/wiki/Texas_Instruments_TMS9900
Peter Smith

1
Eu havia me qualificado 'invariavelmente' com (exceto alguns ajustes), mas o tirei para simplificá-lo. Talvez eu apenas mude para 'geralmente'. Basicamente, se você pode encontrar e entender as exceções, não precisa que eu as destaque. Se você é suficientemente pequeno para ser enganado, isso não importa, porque não lhe causará problemas. TMS9900, isso foi estranho, eu tinha um 99/4 por meus pecados em uma vida anterior, animal estranho!
Neil_UK 9/09/16

O Itanium também possui janelas de registro.
Simon Richter

1
@ ChrisStratton: Embora exista algum precedente para "você não pode usar os registros X e Y" sendo considerado parte de uma "ABI" (por exemplo, registros k0 e k1 nos mips), é um uso incomum. Certamente, existem canais de mensagens secretas indesejados / inseguros entre processos, se o salvamento / restauração desses "registros proibidos pela ABI" não for executado na alternância de contexto. Ou seja, processos que não devem ser capazes de se comunicar podem fazer isso armazenando informações nos registros proibidos e aguardando as alternâncias de contexto.
R ..

12

Os registros devem ser endereçados dentro da instrução. Se houver muitos registros, a instrução será mais longa. Salvar e restaurar o conteúdo do registro para um serviço de interrupção precisa de mais tempo, se houver muitos registros.


5

Como muitas coisas, o número de registros é um compromisso entre custo, complexidade e utilidade.

Os registros são implementados como RAM estática de várias portas, o que os torna mais caros (área de chip) do que outras opções de armazenamento.

Em seguida, eles são acoplados ao conjunto de instruções do processador, aumentando o número de registros aumenta a complexidade do conjunto de instruções. Portanto, se você deseja permanecer compatível com o conjunto de instruções, não pode simplesmente aumentar o número de registros disponíveis na próxima geração de processadores para aumentar a eficiência, os programas não os usariam.

Em seguida, quantos registros você realmente precisa? Há um limite para a sua utilidade. Considere que você escreve um algoritmo que executa alguma operação matemática em 1024 bytes, digamos multiplicar por 5. Com a contagem atual de registros, você acaba com algo como:

load operand1=5
load address
loop: load operand2=byte1@address
multiply Register1 with Register2
store result
increment address
if address = end goto endLoop
jump loop
endLoop:

Agora, se você tivesse 1024 registros e todos os dados armazenados lá, seu programa seria semelhante a:

multiply Register1 with Register2
multiply Register1 with Register3
multiply Register1 with Register4
multiply Register1 with Register5
multiply Register1 with Register6
...

Como cada uma delas é uma instrução diferente, cada uma delas deve ser escrita. Portanto, a memória necessária do programa está explodindo. Depois de perceber isso, você pode querer introduzir algumas instruções como multiply register1 with register(2 to 256),. Mas quando você para, você fornece uma instrução para todas as combinações?

Portanto, talvez os números que temos atualmente sejam uma boa troca entre custo, complexidade e utilidade.


1
Eu acho que o programa multiply Register1 with Register2 multiply Register1 with Register3é muito irreal, pois os dados devem ter vindo direta ou indiretamente de fora do computador, para que os registros precisem ser carregados e os resultados precisem ser usados ​​em algum lugar, direta ou indiretamente, para que os registros precisem ser armazenados. Na realidade, um compilador de otimização decente para uma linguagem de alto nível 'desenrola' o loop do primeiro programa para criar algo como o segundo programa, otimizando o uso de registros, latência de memória, talvez ocupação de cache e velocidade de execução.
gbulmer

1
Não há necessidade de muitas multiply register1 with register(2 to 256)instruções para fins especiais . O pipelining melhora significativamente o rendimento da CPU, especialmente para decodificar e executar instruções. Portanto, o efeito de instruções complexas e massivas de variedade pode ser alcançado usando várias instruções mais simples com uma taxa de execução mais alta. Ter um número maior de registros ajuda a permitir que o compilador gere muitas instruções independentes (aquelas que não compartilham um registro), que podem ser concluídas independentemente, melhorando a taxa de transferência. Seu exemplo = mais registros são melhores.
gbulmer

4

Registros são muito caros. Muito caro. Não são apenas os registros, são todas as conexões de e para os registros. Digamos que você tenha uma instrução reg1 = reg2 + reg3. Para implementar isso rapidamente , você precisa ler os dados de dois registros em um ciclo e gravar em outro registro no segundo ciclo. Agora, se você possui um processador que pode executar várias instruções por ciclo, digamos três instruções, seria necessário ler dados de seis registros a cada ciclo e gravar dados em três registros. É uma quantidade enorme de conexões muito rápidas.

Claro que você pode apenas usar mais transistores. O problema é: a velocidade diminui. Você precisa de mais hardware para escolher entre mais registros. O espaço para o arquivo de registro aumenta. Tudo isso torna as coisas mais lentas. Portanto, com a mesma tecnologia, você poderá ter 16 registros e executar a 2.600 MHz ou 32 registros e executar a 2.400 MHz. Agora, os registros adicionais devem compensar uma queda significativa na velocidade do relógio.


2

Qual fator influenciou o número de registros

- Hierarquia de memória

Registros, cache e RAM são implementados com diferentes tecnologias de armazenamento.

Diferentes tecnologias diferem em

  1. Tempos de acesso
  2. Custo
  3. Densidade

Um exemplo: Os registros internos encontrados em uma CPU são a Memória de acesso aleatório estático , enquanto a memória principal do computador é Memória de acesso aleatório dinâmico

Uma célula binária de RAM estática é implementada usando um circuito de 6 transistores, enquanto uma célula binária de RAM dinâmica é implementada usando um capacitor e um transistor. Comparando SRAM e DRAM

  • A memória SRAM é muito mais rápida que a memória DRAM [Poucos ciclos para acessar a SRAM em comparação com a DRAM]
  • O circuito SRAM consome menos energia que o DRAM
  • A DRAM exige a atualização periódica de todos os bits da memória, diferentemente da SRAM
  • SRAM custa mais que DRAM
  • SRAM tem uma densidade mais baixa em comparação com a DRAM

Portanto, não é prático aumentar o número de memória rápida, cara e com menos densidade. De fato, podemos usar alguns deles, e um programa bem escrito armazenará os dados usados ​​com mais frequência dentro desses registros rápidos, enquanto os dados usados ​​com menos frequência são armazenados na memória mais lenta.

- comprimento da instrução

O endereço dos registradores está incluído em uma instrução, que limita o número de registradores acessíveis com base nos números de bits que podem representar o endereço. Por exemplo, na arquitetura MIPS, a instrução de comprimento de 32 bits contém apenas 5 bits para representar o endereço dos registradores acessíveis, o que limita o número de registradores a 2 5 = 32. Aumentar o número de registradores exigiria aumentar o comprimento da instrução para incluir bits suficientes que poderiam acessar todos os registradores.


2

Se você der uma olhada no conjunto de instruções de um processador, existem várias maneiras de agrupá-los. Por exemplo, todas as ADDinstruções podem ser agrupadas e todas as XORinstruções.

Dentro de cada grupo da mesma instrução, pode haver versões que operam na memória ou nos registradores. É esse subgrupo que define efetivamente o número de registros que o processador possui.

Como um exemplo hipotético de 8 bits, digamos que as $Axinstruções possam ser as ADDinstruções e $Cxpossam ser as XORinstruções. Com esse design, restam apenas quatro bits para definir os operandos!

  • Um pode ter apenas quatro registradores de uso geral e usar dois bits para definir um e dois bits para definir o outro.
  • Ou, pode-se usar o primeiro bit para distinguir variantes "especiais" e os outros 3 bits para definir qual dos oito registradores deve operar com o acumulador ( $x0pode ser o próprio acumulador).
  • Ou, pode-se ter mais do que esse número de registros - mas depois limitar quais registros são acessíveis a quais instruções.

Obviamente, passamos pelos conjuntos de instruções de 8 bits. Mas, ainda assim, essa lógica ajudou a definir conjuntos de registros no passado - continuará a fazê-lo no futuro.

EDITAR (conforme solicitado)

Dizem os quatro primeiros bits são para a instrução: ADD, SUB, XOR, MOV, CMPetc. Há 16 possibilidades aqui. Então, para as instruções em que o registro para registro faz sentido (por exemplo ADD Rx,Ry), você precisa especificar Rxe Ry. Digamos que os próximos dois bits sejam para x, e os dois últimos sejam para y. Portanto:

ADD R1, R2  =>  'ADD' + 'R1' + 'R2' => $A0 + $04 + $02

Com apenas dois bits para definir um registro como este, você só tem espaço para um total de quatro registros!

Como um aparte, você notará que algumas combinações de registradores não fazem sentido. Por exemplo, MOV Rx, Rx(não faz nada) e SUB Rx, Rx(sempre produz 0). Estas podem se tornar instruções de casos especiais:

  1. SUB Rx, Rxpoderia se tornar NOT Rx- uma instrução de um único operando.
  2. MOV Rx, Rxpode se tornar uma MOVinstrução que leva um segundo byte como um valor imediato, interpretado como MOV Rx, #$yy.

Dessa forma, você pode "brincar" com o mapa de instruções, preenchendo os buracos para obter instruções inúteis ou sem sentido para fornecer um conjunto maior de instruções para o programador. Mas, finalmente, o conjunto de instruções define o conjunto de registradores.


Ainda estou confuso, você pode explicar como restam apenas 4 bits para operandos?
Darshan Chaudhary

Verifique minha resposta atualizados
John Burger

1
IMHO esta resposta seria significativamente melhorada movendo o " exemplo hipotético assumido um conjunto de instruções de 8 bits " para o início da pergunta. Eu perdi tempo tentando entender isso, concluí que só fazia sentido para uma instrução de comprimento fixo de 8 bits e, em seguida, continue lendo para descobrir que é esse o caso. IMHO, esse tipo de conjunto de instruções não é muito irrelevante no contexto da questão; todo o espaço de endereçamento poderia ser RAM estática fortemente acoplada. Também acho que a parte que começa com " Algumas combinações de registradores não faz sentido ... " não é relevante para a pergunta e pode ser excluída. Meu $ 0,02
gbulmer 09/09/16

-2

Atualmente, a Intel está usando milhares de registros - centenas por núcleo de CPU. Mas a maior quantidade de dados armazenados em uma CPU está no cache, que indiretamente responde à pergunta. O cache é organizado em camadas, com um pequeno cache L1 rápido e caches L2 e L3 mais lentos. Em certo sentido, o arquivo de registro é L0, ainda mais rápido que L1, mas também menor. Portanto, você poderia aumentar o número de registros, mas isso provavelmente os atrasaria.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.