Eu estava lendo sobre o arduino e a arquitetura do AVR e fiquei preso no ponto em que como o pipeline paralisa ou borbulha é resolvido pela introdução da arquitetura de Harvard no AVR. torna possível carregar o programa sem um operador. Mas como isso ajuda a resolver o problema acima?
12
Respostas:
A arquitetura de Harvard, que aliás foi usada muito antes de os AVRs serem inventados, na verdade possui espaços de endereço separados para a memória do programa e a memória de dados. O que isso traz para a parte é a capacidade de projetar o circuito de forma que um barramento e circuito de controle separados possam ser usados para lidar com o fluxo de informações da memória do programa e o fluxo de informações na memória de dados. O uso de barramentos separados significa que é possível que a busca e a execução do programa continuem sem interrupção de uma transferência ocasional de dados para a memória de dados. Por exemplo, na versão mais simples da arquitetura, a unidade de busca de programas pode estar ocupada buscando a próxima instrução na sequência do programa em paralelo com a operação de transferência de dados que pode ter sido parte da instrução de programa anterior.
Nesse nível mais simples, a arquitetura de Harvard tem uma limitação, pois geralmente não é possível colocar o código do programa na memória de dados e executá-lo a partir daí.
Existem muitas variações e complexidades que podem ser adicionadas a essa forma mais simples da arquitetura que descrevi. Uma adição comum é a adição de armazenamento em cache de instruções ao barramento de informações do programa que permite à unidade de execução de instruções um acesso mais rápido à próxima etapa do programa sem ter que sair para uma memória mais lenta para buscar a etapa do programa sempre que necessário.
fonte
Algumas notas além de Michaels respondem:
1) a arquitetura de Harvard não exige que haja dois espaços separados para dados e código, apenas que eles (principalmente) são buscados em dois barramentos diferentes .
2) o problema resolvido pela arquitetura de Harvard é a contenção de barramento: para um sistema em que a memória de código pode fornecer as instruções com rapidez suficiente para manter a CPU funcionando em velocidade máxima, a carga adicional de busca / armazenamento de dados reduzirá a velocidade da CPU baixa. Esse problema é resolvido por uma arquitetura Hardvard: uma memória que é (um pouco) muito lenta para a velocidade da CPU.
Observe que o cache é outra maneira de resolver esse problema. Muitas vezes, o Harvarding e o cache são usados em combinações interessantes.
Harvard usa dois ônibus. Não há razão inerente para manter dois, em casos muito especiais, mais de dois são usados, principalmente em DSPs (processadores de sinal digital).
O banco de memória (no sentido de distribuir acessos de memória a diferentes conjuntos de chips) pode ser visto como uma espécie de Harvarding dentro do próprio sistema de memória, não com base na distinção de dados / código, mas em certos bits do endereço.
fonte
Uma arquitetura pura de Harvard geralmente permite que um computador com um determinado nível de complexidade seja executado mais rapidamente do que uma arquitetura Von Neuman, desde que nenhum recurso precise ser compartilhado entre o código e as memórias de dados. Se as limitações de pinagem ou outros fatores obrigam o uso de um barramento para acessar os dois espaços de memória, essas vantagens tendem a ser amplamente anuladas.
Uma arquitetura Harvard "pura" será limitada à execução de código que é colocado na memória por algum mecanismo que não seja o processador que executará o código. Isso limita a utilidade dessas arquiteturas para dispositivos cuja finalidade não é definida pela fábrica (ou alguém com equipamento de programação especializado). Duas abordagens podem ser usadas para aliviar esse problema:
Alguns sistemas possuem áreas de código e memória separadas, mas fornecem hardware especial que pode ser solicitado a assumir brevemente o barramento de código, executar algumas operações e retornar o controle à CPU assim que essa operação estiver concluída. Alguns desses sistemas requerem um protocolo bastante elaborado para realizar essas operações, alguns possuem instruções especiais para executar essa tarefa e alguns até observam determinados endereços de "memória de dados" e acionam a aquisição / liberação quando é feita uma tentativa de acessá-los. . Um aspecto fundamental desses sistemas é que existem áreas de memória definidas explicitamente para "código" e "dados"; mesmo que seja possível para a CPU ler e gravar espaço em "código", ela ainda é reconhecida como sendo semanticamente diferente do espaço de dados. '
Uma abordagem alternativa usada em alguns sistemas de ponta é ter um controlador com dois barramentos de memória, um para código e outro para dados, ambos conectados a uma unidade de arbitragem de memória. Essa unidade, por sua vez, se conectou a vários subsistemas de memória usando um barramento de memória separado para cada um. Um acesso de código a um subsistema de memória pode ser processado simultaneamente com um acesso de dados a outro; somente se o código e os dados tentarem acessar o mesmo subsistema simultaneamente, um deles terá que esperar.
Em sistemas que usam essa abordagem, partes de um programa que não sejam críticas para o desempenho podem simplesmente ignorar os limites entre os subsistemas de memória. Se o código e os dados residirem no mesmo subsistema de memória, as coisas não serão executadas tão rapidamente como se estivessem em subsistemas separados, mas para muitas partes de um programa típico que não importam. Em um sistema típico, haverá uma pequena parte do código onde o desempenho realmente importa e funcionará apenas em uma pequena parte dos dados mantidos pelo sistema. Se alguém tivesse um sistema com 16K de RAM dividido em duas partições de 8K, seria possível usar instruções do vinculador para garantir que o código crítico de desempenho estivesse localizado próximo ao início do espaço de memória geral e os dados críticos de desempenho estivessem próximos ao fim. Se o tamanho geral do código aumentar para, por exemplo, 9K, o código no último 1K seria mais lento que o código colocado em outro lugar, mas esse código não seria crítico para o desempenho. Da mesma forma, se o código tivesse, por exemplo, apenas 6K, mas os dados aumentassem para 9K, o acesso ao 1K de dados mais baixo seria lento, mas se os dados críticos de desempenho estivessem localizados em outro lugar, isso não representaria um problema.
Observe que, embora o desempenho seja ideal se o código estiver abaixo de 8K e os dados estiverem abaixo de 8K, o design do sistema de memória mencionado acima não imporá nenhuma partição estrita entre código e espaço de dados. Se um programa precisar apenas de 1K de dados, o código poderá crescer até 15K. Se precisar apenas de 2K de código, os dados poderão aumentar para 14K. Muito mais versátil do que ter uma área de 8K apenas para código e uma área de 8K apenas para dados.
fonte
Um aspecto que não foi discutido é que, para microcontroladores pequenos, normalmente com apenas um barramento de endereços de 16 bits, uma arquitetura de Harvard dobra (ou triplica) efetivamente o espaço de endereço. Você pode ter 64K de código, 64K de RAM e 64k de E / S mapeada em memória (se o sistema estiver usando E / S mapeada em memória em vez de números de porta, o último já separará o endereço de E / S do código e Espaços de RAM).
Caso contrário, você deve compactar o código, a RAM e, opcionalmente, o endereço de E / S, tudo dentro do mesmo espaço de endereço de 64K.
fonte