A resposta curta
As etapas de decodificação e execução da instrução são executadas em paralelo com a próxima etapa da instrução anterior. Essa técnica é conhecida como pipelining. Veja Em processadores RISC abaixo.
Uma arquitetura RISC de emissão única normalmente mede em média um pouco menos de uma instrução por ciclo devido a estados de espera e tempo gasto para operações de carregamento / armazenamento que atingem a memória, em vez de apenas serem registradas para se registrar. Os slots de atraso oferecem um gancho arquitetural que pode permitir que você recupere parte desse tempo. Consulte Processadores RISC abaixo.
Um ciclo de instruções é o período de tempo necessário para executar uma instrução. Isso varia de acordo com a arquitetura e (em alguns casos) as instruções. Por exemplo, a maioria das instruções sobre algo como um MIPS R2000 / 3000 leva um ciclo. As instruções que envolvem o acesso à memória (carregamento / armazenamento, ramificação) levam mais de um ciclo, embora os slots de atraso signifiquem que você possa executar outra coisa (possivelmente apenas um NOP) no slot de atraso. Arquiteturas sem pipeline podem ter ciclos de instruções de vários ciclos de clock, geralmente variando com o modo de endereçamento. Consulte Processadores RISC, arquiteturas CISC tradicionais e arquiteturas conectadas abaixo.
Projetos de questões múltiplas podem embaçar esse conceito, executando mais de uma instrução em paralelo.
Os processadores CISC podem ter instruções que levam diferentes períodos de tempo. O número exato de ciclos de clock depende da arquitetura e das instruções. O número variável de ciclos de clock adotados nos ISA da CISC é uma das razões pelas quais é difícil incorporar arquiteturas com pipelines pesadas. Veja as arquiteturas tradicionais do CISC abaixo.
A resposta mais longa
Para um único problema MIPS, SPARC ou outra CPU, todas as instruções (para uma primeira aproximação) são emitidas em um ciclo, embora possam ter algo conhecido como 'slot de atraso'.
Em processadores RISC
Nesse contexto, uma única CPU de problema é aquela em que a CPU não faz nenhuma análise de dependência imediata e emissão paralela de instruções da mesma forma que as CPUs modernas, ou seja, elas têm apenas uma unidade de execução que executa as instruções em a ordem em que são lidos da memória. Mais sobre isso mais tarde.
A maioria dos processadores RISC mais antigos são de edição única e esses tipos ainda são amplamente utilizados em sistemas embarcados. Um núcleo RISC inteiro de edição única de 32 bits pode ser implementado em cerca de 25.000 a 30.000 portas, portanto, os núcleos de CPU desse tipo têm consumo de energia muito baixo e pegadas muito pequenas. Isso os torna fáceis e baratos de integrar nos produtos SOC (sistema no chip).
Os projetos de CPU do RISC são canalizados - o processamento da instrução é feito em vários estágios, com cada instrução sendo passada pelo pipeline para o próximo estágio a cada ciclo de clock. Na maioria dos casos, uma CPU em pipeline de um único problema executará algo próximo a uma instrução por ciclo de clock.
Algumas arquiteturas têm instruções como ramificação ou carregamento / armazenamento da memória, onde o ciclo adicional utilizado pelo acesso à memória é visível para o código.
Por exemplo, em um projeto SPARC V7 / V8 , a próxima instrução após a execução de uma ramificação antes da ocorrência da ramificação. Normalmente, você colocaria um NOP no slot após a ramificação, mas poderia colocar outra instrução nele se encontrasse algo útil para fazer.
A arquitetura MIPS R2000 / R3000 tinha um slot de atraso semelhante nas instruções de carregamento / armazenamento. Se você carregasse um valor da memória, ele não seria exibido no registro por outro ciclo. Você poderia colocar um NOP no slot ou fazer outra coisa se pudesse encontrar algo útil para fazer que não dependesse da operação de carregamento que você acabou de emitir.
Se a memória estiver mais lenta que a CPU, o que geralmente ocorre, você poderá obter estados de espera adicionais nos acessos à memória. Os estados de espera congelam a CPU por um ou mais ciclos de clock até que o acesso à memória seja concluído. Na prática, esses estados de espera e tempo extra para acessos à memória significam que os designs de CPU de emissão única têm em média um pouco menos de uma instrução por ciclo de clock. Os slots de atraso oferecem algumas oportunidades possíveis para otimizar o código executando outras instruções enquanto ocorre uma operação de memória.
Processadores CISC tradicionais
Os processadores CISC eram projetos que podiam ter instruções com duração variável. Freqüentemente, eles tinham instruções mais complexas implementadas diretamente no hardware que precisavam ser executadas no software em uma CPU RISC.
A maioria das arquiteturas de mainframe e praticamente todos os projetos de PCs até o M68K e o intel 386 eram CPUs CISC microcodificadas tradicionais. Esses projetos provaram ser mais lentos por relógio e usavam mais portas do que as CPUs RISC.
Microcódigo
Um exemplo de uma arquitetura microcodificada (MOS 6502) pode ser visto em emulação aqui . O microcódigo pode ser visto na parte superior da imagem.
O microcódigo controla os fluxos de dados e as ações ativadas na CPU para executar instruções. Ao percorrer as etapas do microcódigo, você pode ativar as partes de uma CPU, mover dados pelas ALUs ou executar outras etapas. Componentes reutilizáveis na CPU podem ser coordenados em vários ciclos de clock para executar uma instrução. No caso do 6502, algumas ações em pipeline também podem ser executadas pelo microcódigo.
Os projetos de microcodificação usavam menos silício do que os chips conectados à custa de potencialmente levar vários ciclos de relógio para concluir uma instrução. Dependendo do design, essas CPUs levariam vários períodos de tempo por instrução.
Arquiteturas conectadas
Os projetos conectados (não necessariamente mutuamente exclusivos com microcódigo) executam uma instrução de forma síncrona ou podem ter seus próprios coordenadores para fazer algo em vários ciclos de clock. Eles geralmente são mais rápidos às custas de hardware mais dedicado e, portanto, são mais caros de implementar do que um design microcodificado de funcionalidade equivalente.
Um exemplo famoso disso foi a CPU Amdahl 470/6 original , que foi um substituto para a CPU em certos modelos IBM System / 370. A CPU da Amdahl era um design com fio no momento em que as 370 CPUs da IBM eram fortemente baseadas em microcódigo. A CPU da Amdahl foi cerca de três vezes mais rápida que as da IBM substituídas.
Desnecessário dizer que a IBM não se divertiu e isso resultou em uma batalha judicial que acabou forçando a IBM a abrir sua arquitetura de mainframe até que o decreto de consentimento expirasse alguns anos atrás.
Normalmente, um design com fio desse tipo ainda não era tão rápido como uma CPU RISC quanto os diferentes tempos e formatos das instruções não permitiam tanto espaço para pipelines quanto um design RISC.
Projetos de várias edições
As CPUs mais modernas são várias arquiteturas de problemas que podem processar mais de uma instrução por vez em um único encadeamento. O chip pode fazer uma análise de dependência dinâmica no fluxo de instruções recebidas e emitir instruções em paralelo, onde não há dependência do resultado de um cálculo anterior.
A taxa de transferência desses chips depende de quanto paralelismo pode ser alcançado no código, mas a maioria das CPUs modernas calcula a média de várias instruções por ciclo na maioria dos códigos.
A Intel moderna e outras CPUs ISA x86 / X64 têm uma camada que interpreta o conjunto de instruções CISC da velha escola em micro instruções que podem ser alimentadas através de um núcleo de múltiplos problemas no estilo RISC em pipeline. Isso adiciona alguma sobrecarga que não está presente nas CPUs com ISAs projetadas para pipelining (ou seja, arquiteturas RISC, como ARM ou PowerPC).
Projetos VLIW
Os projetos VLIW, dos quais o Intel Itanium é talvez o mais conhecido, nunca decolaram como arquiteturas convencionais, mas no IIRC existem várias arquiteturas DSP que usam esse tipo de design. Um design VLIW torna vários problemas explícitos com uma palavra de instrução contendo mais de uma instrução emitida em paralelo.
Isso dependia de bons compiladores de otimização, que identificavam dependências e oportunidades de paralelismo, colocando instruções nos vários slots disponíveis em cada palavra de instrução.
As arquiteturas VLIW funcionam muito bem para aplicativos numéricos, pois as operações de matriz / matriz tendem a oferecer oportunidades para um paralelismo extensivo. O Itanium possuía um nicho de mercado em aplicativos de supercomputação por um tempo e havia pelo menos uma arquitetura de supercomputador - o Multiflow TRACE - foi produzida usando um ISA desse tipo.
Memória e cache
As CPUs modernas são muito, muito mais rápidas que a memória; portanto, as leituras diretas da memória podem gerar centenas de estados de espera que bloqueiam a CPU até que o acesso à memória seja concluído. O cache, agora feito em várias camadas, mantém os locais de memória usados mais recentemente no cache. Como as CPUs normalmente passam a grande maioria do tempo executando o código em loops, isso significa que você obtém boas taxas de acerto ao reutilizar os locais de memória usados recentemente. Essa propriedade é chamada 'localidade de referência'.
Onde você obtém a localidade de referência, a CPU pode operar na velocidade ideal. As falhas de cache até o próximo nível incorrem em vários estados de espera; falhas de cache na memória principal podem incorrer em centenas.
Assim, a taxa de transferência real dos chips da CPU pode ser fortemente dependente da eficiência dos padrões de acesso à memória. Livros inteiros foram escritos sobre como otimizar código para isso, e é um tópico complexo por si só.