capítulo 4 memória - unicampattux/cap4_memoria.pdfcircuito removendo as conexões que não devem...
TRANSCRIPT
Capítulo 4 – Memória
Prof. Romis Attux
EA075 – 2015
Obs: Os slides são parcialmente baseados nos dos autores do livro texto e do Prof. Levy Boccato
Partes e Ponderações
Um sistema embarcado possui três grandes categorias
de funcionalidades: processamento, armazenagem e
comunicação.
“Processamento” abrange a atuação no sentido de
modificar dados.
“Armazenagem” corresponde à tarefa de guardar dados
para uso posterior.
“Comunicação” diz respeito à transferência de dados.
Trataremos neste capítulo do problema de
armazenagem, partindo de conceitos de memória.
Aspectos Básicos
Uma memória é capaz de armazenar uma grande quantidade de bits.
Basicamente, pode-se pensar em m palavras com n bits cada, num total de m*n bits, como mostrado abaixo.
Aspectos Básicos
Uma memória desse tipo, “m por n”, pode ser vista na próxima figura em mais detalhe. Note que essa memória precisa de log2(m) bits para especificar o endereço de uma palavra e terá n bits para entrada e saída de dados.
Por exemplo, uma memória 4096 por 8 precisará de 12 bits de endereçamento e 8 bits de dados.
Leitura e Escrita
Ler a memória significa acessar o conteúdo de dados
associado a determinado endereço (acessar os dados
contidos numa palavra).
Escrever corresponde à operação de inserir dados no
endereço correspondente a uma palavra.
Um acesso à memória pode ser tanto para escrita
quanto para leitura.
Uma memória que pode ser lida e escrita requer um
sinal de controle, r/w, que indica a operação desejada.
Também é usual que haja um sinal de enable.
Tipos de Memória
Classicamente, divide-se a memória em dois tipos
fundamentais: ROM e RAM.
Uma memória ROM (read-only memory) é,
historicamente, uma memória que o processador
apenas lê, e que é não-volátil (guarda informação sem
estar ligada a uma fonte de energia).
Uma memória RAM (random-acess memory) é,
historicamente, vista como uma memória em que o
processador pode ler e escrever com certa agilidade,
mas que perde seu conteúdo se não alimentada.
Hibridização
Atualmente, esses conceitos não são mais tão cristalizados. É possível escrever em memórias ROM via processador (EEPROM, memória Flash) e existem RAMs não-voláteis.
Discutiremos então os tipos de memória em termos de sua capacidade de escrita e da permanência do conteúdo armazenado.
Possibilidade de Escrita
Todas as memórias podem ser lidas e escritas.
Discutiremos aqui os diferentes tipos de escrita em
memórias, que definem conceitos fundamentais.
Num extremo, temos as memórias em que o
processador escreve com toda agilidade simplesmente
especificando endereço, dados e sinais de controle.
Num meio-termo, temos memórias que podem sofrer
escrita pelo processador, mas num ritmo mais lento.
Por fim, temos memórias que só podem ser escritas
por um aparato especial denominado “programador”.
Retenção dos Dados
Por outro lado, temos a questão da duração dos dados
armazenados. No nível mais baixo nesse quesito estão
as memórias que começam a ter sua informação
perdida quase imediatamente após o processo de
escrita (e precisam de “refreshes” constantes). Em
seguida há memórias que perdem seu conteúdo assim
que deixam de ser alimentadas. Depois há memórias
que podem manter seu conteúdo por dias, meses ou
anos após o desligamento de sua fonte de alimentação.
Por fim, existem memórias que virtualmente nunca
perdem seu conteúdo (exceto em caso de dano ao
chip).
Categorias
Volátil / Não-Volátil Programável no sistema / Não-
programável no sistema. Esses conceitos terminam por
estabelecer um compromisso (trade-off).
Categorias
Write ability and storage permanence of memories,
showing relative degrees along each axis (not to scale).
External
programmer
OR in-system,
block-oriented
writes, 1,000s
of cycles
Battery
life (10
years)
Write
ability
EPROM
Mask-programmed ROM
EEPROM FLASH
NVRAM
SRAM/DRAM
Sto
rage
per
man
ence
Nonvolatile
In-system
programmable
Ideal memory
OTP ROM
During
fabrication
only
External
programmer,
1,000s
of cycles
External
programmer,
one time only
External
programmer
OR in-system,
1,000s
of cycles
In-system, fast
writes,
unlimited
cycles
Near
zero
Tens of
years
Life of
product
Memória ROM - Fundamentos
Uma ROM tradicional é uma memória não-volátil que pode ser lida por um processador, mas não sofre escrita por ele. A escrita nela é feita por meios externos de programação.
Portanto, uma ROM é programada antes de ser usada num sistema embarcado, e, depois, seu conteúdo não é mais modificado.
A figura a seguir a seguir mostra o diagrama de uma memória ROM.
Algumas Funções Possíveis
Guardar o programa de um sistema de propósito geral.
Guardar dados relevantes para o sistema embarcado (lookup tables, por exemplo).
Implementar circuitos combinacionais, caso em que a ROM guarda, em essência, a tabela-verdade do circuito.
ROM – Esquema Básico
8 × 4 ROM
3×8 decoder
Q0 Q3
A0
enable
A2
word 0
word 1
A1
Q2 Q1
programmable connection wired-OR
word line
data line
word 2
Internal view
ROM – Esquema Básico
Nesta memória, o conteúdo é programado fisicamente pela presença e ausência de conexões.
Por exemplo, se o enable estiver habilitado e pedirmos a palavra de endereço 010, teremos como resposta o dado 1010, devido às conexões ou ausência delas.
Perceba que o decodificador ativa a linha da palavra desejada e as ligações formam a informação.
Programação
Como programas as conexões? Há várias formas de fazer isso, o que define diferentes tipos de memórias ROM.
Em ordem de crescente simplicidade de escrita, falaremos sobre mask-programmed ROM, one-time programmable ROM, erasable programmable ROM (EPROM), electrically erasable programmable ROM (EEPROM) e memória Flash. As duas últimas talvez nem devessem ser chamadas de ROM...
Mask-Programmed ROM
Nesse caso, as conexões são definidas na fabricação do chip por meio de máscaras adequadamente projetadas.
Não há a possibilidade de reescrita, e o conteúdo só é perdido se houver dano ao circuito.
OTP ROM
Trata-se de uma ROM programada pelo usuário uma única vez
(OTP – one-time programmable).
Para programar uma PROM, o usuário fornece um arquivo que
indica o padrão de conexões desejado. Um equipamento
denominado “programmer” então queima diversos fusíveis do
circuito removendo as conexões que não devem existir. É por isso
que essa PROM só pode ser usada uma vez.
Esse tipo de memória não sofre modificações após a escrita (exceto
se mais fusíveis forem queimados ou houver dano), sendo de
robustez atraente para produtos finais. Veremos que outras PROMs
podem sofrer modificações acidentais com maior probabilidade.
EPROM – Erasable
Programmable ROM EPROMs são memórias que podem ser escritas e apagadas.
Elas usam transistores MOS como elementos de
armazenagem, numa configuração de gate flutuante. O
programmer injeta elétrons nesse gate usando tensões
relativamente altas (12 a 25 V), fazendo com que os elétrons
tunelem pelo isolante, como mostrado na figura a seguir.
Quando se retira a tensão, os elétrons ficam presos no gate,
e houve a programação de um bit “0”.
Ler uma EPROM é muito mais rápido que escrever nela, já
que não é preciso realizar a programação.
EPROM – Erasable
Programmable ROM Para apagar a memória, usa-se a
incidência de luz ultravioleta sobre o chip por 5 a 30 minutos, após o que o chip pode ser reprogramado.
Para que a luz UV chegue ao chip, o encapsulamento contém uma janela de quartzo (windowed device).
EPROMs padrão guardam seu conteúdo por pelo menos 10 anos.
Comparação
Em comparação com a OTP-ROM, uma EPROM possui menor tempo de armazenagem garantida (10 anos) e há risco de que o conteúdo seja corrompido em ambientes com muito ruído elétrico ou radiação. No produto final, é recomendável cobrir as janelas dos chips para diminuir a chance de mudanças espúrias.
EEPROM
Uma EEPROM é uma electrically erasable PROM, ou seja, uma
PROM apagável eletricamente.
Portanto, não só a programação é feita de maneira elétrica, mas
também o apagamento e programação.
Portanto, trata-se de uma memória que pode sofrer tanto leitura
quanto escrita (a escrita segue um ciclo de apagamento e escrita).
EEPROMs tipicamente são munidas de um controlador de memória
que provê uma interface simples ao usuário. Nesse caso,
praticamente diluem-se as fronteiras entre ROM e RAM, embora a
escrita numa EEPROM seja um processo mais custoso que a
leitura.
Memória Flash
A memória flash também é baseada no princípio de gate flutuante, mas permite de maneira orgânica o apagamento de blocos de palavras.
Isso é interessante, pois agiliza a operação do sistema de memória quando se lida com grandes quantidades de dados.
Memória RAM - Fundamentos
Memórias RAM (random-access memory) são memórias que pode ser lidas e escritas com facilidade.
Escrever numa RAM envolve um custo parecido com o de uma leitura, em contraste com o que ocorre com as ROM programáveis, nas quais a escrita é bem mais custosa que a leitura.
Tipicamente, RAMs são memórias voláteis.
Memória RAM – Exemplo
Simples A seguir apresentamos o diagrama de uma memória RAM simples.
Note a presença de um sinal r/w e do fluxo bidirecional de dados.
enable
2k × n read and write
memory
A0 …
r/w
…
Q0 Qn-1
Ak-1
external view
Memória RAM - Estrutura
O nome “acesso aleatório” vem em contraste com memórias de acesso sequencial, como fitas magnéticas, por exemplo.
Há dois tipos básicos de RAM – SRAM (static RAM) e DRAM (dynamic RAM). Na primeira, a informação é gravada numa estrutura equivalente à de um flip-flop, e, na segunda, a unidade de gravação básica é um capacitor.
SRAM – Estrutura de
Armazenagem Uma SRAM utiliza uma estrutura de flip-flop para armazenar
a informação. A estrutura retém a informação enquanto é
alimentada, em contraste com o que ocorre com uma DRAM.
Utiliza-se tipicamente SRAM em partes da memória que
requerem alto desempenho (e.g. cache).
Data
W
Data'
SRAM
DRAM – Estrutura de
Armazenagem Uma DRAM utiliza uma estrutura contendo um
transistor MOS e um capacitor para guardar a
informação.
Cada bit, portanto, requer apenas um transistor, mas
isso ao custo de que a informação armazenada no
capacitor tende gradualmente a se perder (pelo
processo de descarga). Assim, cada célula precisa
sofrer periodicamente um processo de refresh.
Data
W
DRAM
DRAM – Estrutura de
Armazenagem A taxa de refresh mínima de uma
memória DRAM típica é de cerca de 15 microssegundos.
Pela forma como DRAMs são projetadas, a leitura de uma célula já ocasiona seu refresh.
DRAMs tendem a ser mais lentas que SRAMs.
NVRAM – RAM Não-Volátil
Uma NVRAM é uma memória RAM não-volátil, ou seja, que é capaz de guardar seu conteúdo mesmo sob uma perda de alimentação.
Uma possibilidade é ter, por exemplo, uma SRAM com uma bateria dedicada (algumas baterias podem durar até 10 anos).
Outra é ter uma SRAM acoplada a uma EEPROM ou flash espelho que guarda de maneira perene o conteúdo da memória e restaura esse conteúdo em caso de perda.
Composição de Memórias
O projetista de um sistema embarcado pode se deparar com a necessidade de utilizar certa configuração de memórias tendo apenas componentes de tamanho diferente.
Por exemplo, ele pode precisar de 2k x 8 ROMs, mas ter apenas 4k x 16 ROMs. Por outro lado, ele pode se ver na situação contrária.
Composição de Memórias
Quando a memória disponível é maior que o necessário, o projetista pode usar apenas as linhas menos significativas de endereços e dados e ignorar as demais.
O caso em que a memória disponível é menor que o necessário requer mais esforço.
Suponhamos, primeiramente, o caso em que as memórias tem o número certo de palavras, mas as palavras têm tamanho insuficiente. Nesse caso, os chips podem ser concatenados como a seguir.
Composição de Memórias
Por outro lado, suponhamos que as memórias tenham o tamanho de palavra correto, mas número insuficiente de palavras. Neste caso, criam-se linhas adicionais de endereço e utilizam-se decodificadores.
Por exemplo, suponhamos que precisemos de uma ROM com o dobro de palavras das presentes nos chips de que dispomos. É possível operar como mostrado a seguir (criando uma linha de endereço adicional que seleciona o chip).
Composição de Memórias
Se fosse preciso quadruplicar (em vez de dobrar) o tamanho da memória, poder-se-ia usar um decodificador 2 x 4 e criar duas linhas de endereço adicionais.
Se tivermos uma combinação dos dois casos (palavras pequenas e poucas palavras), podemos combinar as duas técnicas. Faz-se a concatenação e, em seguida, aplica-se o método de inclusão de decodificadores. Um esboço é mostrado a seguir.
Hierarquia de Memória
Quando se projeta um sistema de memória, vive-se um dilema: deseja-se memória rápida e barata.
No entanto, memória rápida tende a ser cara e memória barata tende a ser lenta.
Um caminho para se atingir um compromisso é criar uma hierarquia de memória, como ilustrado a seguir.
Hierarquia de Memória
Do ponto de vista de sistemas embarcados, utiliza-se
uma memória maior e mais lenta (Main Memory) para
guardar o programa e os dados.
Utiliza-se também uma memória menor e mais rápida
(Cache), que é mais cara, para guardar blocos
acessados na memória principal. Por uma questão de
localidade, é provável que esses blocos sofram
diversos usos antes de serem trocados.
Embora o diagrama mostre apenas uma memória
cache, pode-se construí-la usando, eventualmente,
vários níveis.
Hierarquia de Memória
Alguns sistemas envolvem outras formas de memória, como discos magnéticos e fitas, mas, em sistemas embarcados, isso não é comum.
Normalmente, projeta-se memória cache com tecnologia SRAM, por sua velocidade, o que explica por que a memória cache é mais cara e menor que a memória principal (por exemplo, uma DRAM). Também explica-se seu tamanho pelo fato de ela estar no mesmo chip do processador em geral.
Memória Cache
Tipicamente, uma memória cache opera da seguinte forma: quando se deseja acessar um endereço de memória, verifica-se primeiro se há uma cópia na cache.
Se houver, tem-se um acerto (cache hit), e o acesso é rápido. Se não for o caso, tem-se uma falha (cache miss), e tipicamente se transporta o endereço e alguns vizinhos para a cache.
Essa descrição levanta muita possibilidades, que buscaremos discutir a seguir.
Mapeamento Direto
A figura a seguir ilustra o esquema. Note que o endereço
possui dois campos, index e tag. Index corresponde ao
endereço no espaço da cache, e, portanto, seu número de
bits é log2(tamanho_cache). O tamanho aqui quer dizer
número de linhas, como veremos adiante.
Perceba que vários endereços da memória principal
apontarão para o mesmo endereço na cache. Por esse
motivo, armazena-se na cache, juntamente com o conteúdo
da memória, a tag. Se os endereços de index batem, verifica-
se se há coincidência de tags e verifica-se um bit de validade
(V), que revela se o dado corresponde a uma informação
válida trazida da memória principal.
Mapeamento Direto
Por fim, usa-se o campo offset para buscar, numa linha da cache, a palavra específica.
Uma linha da cache (ou bloco) é um número de endereços adjacentes inseparáveis trazidos da memória principal para a cache. Tamanhos típicos vão de 4 a 8 endereços.
Mapeamento Totalmente
Associativo Neste caso, cada endereço de cache contém
não só o conteúdo da memória, mas o endereço completo.
Para verificar se determinado conteúdo está na cache, realiza a comparação da tag do endereço com todas as tags armazenadas.
Em caso de cache hit, utiliza-se o offset para buscar, dentro do bloco, a palavra desejada.
Note que o número de linhas da cache não é determinado pelo formato do endereço.
Mapeamento Associativo por
Conjuntos Nesse caso, busca-se um compromisso entre os
dois paradigmas vistos anteriormente.
Como no mapeamento direto, o campo index
mapeia cada endereço de memória num único
campo da cache, mas agora esse campo contém
os tags de um ou mais blocos de palavras
(formando um conjunto). Para resolver essa
ambiguidade, faz-se, para esses blocos, uma
comparação simultânea (associativa) das tags.
Uma cache com conjuntos de N blocos é
chamada de N-way set-associative cache (N = 2,
4, 8 são opções comuns).
Comparações
O mapeamento direto é relativamente simples de
implementar, mas pode levar a várias
ocorrências de cache miss se duas ou mais
linhas com o mesmo index são acessadas
frequentemente, pois elas se expulsarão
mutuamente da cache.
Por outro lado, caches puramente associativas
são eficientes, mas requerem uma lógica de
comparação complexa.
Caches associativas por conjunto representam
um meio-termo entre ambos os casos.
Políticas de Substituição
A política de substituição de uma cache é o método para decidir qual linha substituir quando se usa um método associativo ou associativo por conjuntos. No caso direto, não há escolha.
Uma primeira política é escolher aleatoriamente o bloco. Embora seja simples de implementar, a política nada faz para aproveitar um bloco que possa ser usado mais vezes.
Políticas de Substituição
Outra política é fazer a substituição do bloco least recently used (LRU). Isso leva a um bom desempenho, mas requer hardware complexo para manter o controle dos acessos aos blocos.
Por fim, a política FIFO (First-In / First-Out) mantém uma fila de tamanho N para regular a entrada e a saída dos blocos.
Políticas de Escrita
Quando se escreve num dado contido na memória cache, é preciso restaurar a coerência entre a informação contida nesta memória e na memória principal. Há duas grandes políticas para isso: write-through e write-back.
Na técnica write-through, cada vez que se escreve numa palavra da cache, atualiza-se a memória principal. Isso é simples mas pode levar a escritas inúteis e lentas, já que a informação na cache poderia vir a ser reescrita antes de voltar à memória principal.
Políticas de Escrita
Por outro lado, na política write-back, só se atualiza a memória principal quando o bloco é substituído e se ele foi escrito. Nesse caso, é preciso dispor de um bit extra, chamado de dirty bit, em cada bloco, para indicar a necessidade de atualizar a memória principal ao se retirar o bloco da cache.
Impacto no Desempenho do
Sistema O projeto e configuração de caches
pode ter um grande impacto no desempenho do sistema e no seu consumo de potência.
Alguns parâmetros fundamentais: tamanho da cache, grau de associatividade, tamanho de bloco (ou linha).
O tamanho da cache é medido diretamente pelo número de bytes que ela pode conter.
Impacto no Desempenho do
Sistema Aumentar a memória leva a uma
diminuição em cache misses, mas o acesso a palavras pode ser mais lento.
Um exemplo do livro-texto ajuda a tornar isso mais claro. Imagine que projetemos uma memória cache pequena, de 2 Kbytes, para o processador. Ela possui 15% de misses. O custo de acessar a memória principal é de 20 ciclos, e o custo de acessar apenas a cache é de 2 ciclos. Nesse caso, temos 0,85*2 + 0,15*20 = 4,7 ciclos em média.
Impacto no Desempenho do
Sistema Suponha agora que tenhamos uma
memória de 4Kbytes. Ela tem taxa de acerto de 93,5%, mas requer um ciclo extra para acesso. Temos 3*0,935 + 0,065*20 = 4,105 ciclos. Há uma melhora. Porém suponha que usemos agora uma memória de 8Kbytes. Nesse caso, temos 94,435% de acerto, mas a um custo de um ciclo a mais para acesso à cache. Agora, teríamos 4,8904 ciclos em média, uma piora.
Impacto no Desempenho do
Sistema Note que um aumento indiscriminado
pode levar a uma piora em termos de tempo. Usualmente os projetistas evitam isso tornando a cache associativa ou aumentando o tamanho de bloco. No entanto, também há penalidades de latência nesses casos.
Para concluir, apresentamos um gráfico que mostra o efeito do grau de associatividade no desempenho da cache para um conjunto de benchmarks.