Quantos endereços de memória a RAM em meu computador aguenta?
Algum dia é divertido olhar para o nível superficial da experiência de computação, e em outros dias é divertido mergulhar direto no funcionamento interno. Hoje vamos dar uma olhada na estrutura da memória do computador e em quantas coisas você pode colocar em uma memória RAM.
A sessão de perguntas e respostas de hoje nos é oferecida por cortesia do SuperUser - uma subdivisão do Stack Exchange, um agrupamento de sites de perguntas e respostas conduzido pela comunidade..
A questão
O leitor do SuperUser, Johan Smohan, está lidando com o modo como o tipo de processador e o tamanho da memória trabalham juntos para obter um número total de endereços. Ele escreve:
Quantos endereços de memória podemos obter com um processador de 32 bits e 1 GB de RAM e quantos com um processador de 64 bits?
Eu acho que é algo assim:
1GB de ram dividido por 32 bits 4 bits (?) Para obter o número de endereços de memória?
Eu li na Wikipedia que 1 endereços de memória tem 32 bits de largura ou 4 octetos (1 octeto = 8 bits), comparado a um processador de 64 bits onde 1 endereços de memória ou 1 inteiro tem 64 bits de largura ou 8 octetos. Mas não sei se entendi corretamente também.
Estes são os tipos de perguntas que podem manter um geek curioso à noite. Quantos endereços estão disponíveis em cada um dos sistemas hipotéticos de Johan??
A resposta
O colaborador do SuperUser Gronostaj oferece algumas dicas sobre como a RAM é dividida e utilizada:
Resposta curta: O número de endereços disponíveis é igual ao menor deles:
- Tamanho da memória em bytes
- Maior número inteiro sem sinal que pode ser salvo na palavra da máquina da CPU
Resposta longa e explicação do acima:
Memória consiste em bytes (B). Cada byte consiste em 8 bits (b).
1 B = 8 b
1 GB de RAM é na verdade 1 GiB (gibibyte, não gigabyte). A diferença é:
1 GB = 10 ^ 9 B = 1 000 000 000 B 1 GiB = 2 ^ 30 B = 1 073 741 824 B
Cada byte de memória tem seu próprio endereço, não importa quão grande seja a palavra da máquina do processador. Por exemplo. A CPU Intel 8086 tinha 16 bits e estava lidando com memória por bytes, assim como as modernas CPUs de 32 e 64 bits. Essa é a causa do primeiro limite - você não pode ter mais endereços do que bytes de memória.
O endereço de memória é apenas um número de bytes que a CPU precisa pular do começo da memória para chegar àquela que está procurando.
- Para acessar o primeiro byte ele tem que pular 0 bytes, então o endereço do primeiro byte é 0.
- Para acessar o segundo byte, ele precisa pular 1 byte, então seu endereço é 1.
- (e assim por diante… )
- Para acessar o último byte, a CPU pula 1073741823 bytes, então seu endereço é 1073741823.
Agora você precisa saber o que significa 32 bits. Como mencionei antes, é o tamanho de uma palavra de máquina.
Palavra de máquina é a quantidade de memória que a CPU usa para armazenar números (em RAM, cache ou registros internos). CPU de 32 bits usa 32 bits (4 bytes) para armazenar números. Endereços de memória também são números, portanto, em uma CPU de 32 bits, o endereço de memória consiste em 32 bits..
Agora pense sobre isso: se você tem um bit, você pode salvar dois valores nele: 0 ou 1. Adicione mais um bit e você tem quatro valores: 0, 1, 2, 3. Em três bits, você pode salvar oito valores : 0, 1, 2… 6, 7. Este é na verdade um sistema binário e funciona assim:
Binário decimal 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001 10 1010 11 1011 12 1100 13 1101 14 1110 15 1111
Funciona exatamente como a adição usual, mas o dígito máximo é 1, não 9. O decimal 0 é
0000
, então você adiciona 1 e obtém0001
, adicione um mais uma vez e você tem0010
. O que aconteceu aqui é como ter decimal09
e adicionando um: você altera 9 para 0 e incrementa o próximo dígito.Do exemplo acima você pode ver que há sempre um valor máximo que você pode manter em um número com um número constante de bits - porque quando todos os bits são 1 e você tenta aumentar o valor em 1, todos os bits se tornarão 0, quebrando assim número. É chamado de estouro de inteiro e causa muitos problemas desagradáveis, tanto para usuários quanto para desenvolvedores.
11111111 = 255 + 1 ----------- 100000000 = 0 (9 bits aqui, então 1 é cortado)
- Para 1 bit, o maior valor é 1,
- 2 bits - 3,
- 3 bits - 7,
- 4 bits - 15
O maior número possível é sempre 2 ^ N-1, onde N é o número de bits. Como eu disse antes, um endereço de memória é um número e também tem um valor máximo. É por isso que o tamanho da palavra da máquina também é um limite para o número de endereços de memória disponíveis - às vezes, sua CPU simplesmente não consegue processar números grandes o suficiente para endereçar mais memória.
Então, em 32 bits, você pode manter números de 0 a 2 ^ 32-1, e isso é 4 294 967 295. É mais do que o maior endereço em 1 GB RAM, portanto, em sua quantidade específica de RAM será o fator limitante.
O limite de RAM para a CPU de 32 bits é teoricamente de 4 GB (2 ^ 32) e para a CPU de 64 bits é de 16 EB (exabytes, 1 EB = 2 ^ 30 GB). Em outras palavras, a CPU de 64 bits poderia resolver toda a Internet ... 200 vezes;) (estimado por WolframAlpha).
No entanto, em sistemas operacionais reais, as CPUs de 32 bits podem endereçar cerca de 3 GiB de RAM. Isso é devido à arquitetura interna do sistema operacional - alguns endereços são reservados para outros propósitos. Você pode ler mais sobre essa barreira de 3 GB na Wikipedia. Você pode levantar esse limite com a extensão de endereço físico.
Falando sobre endereçamento de memória, há poucas coisas que devo mencionar: memória virtual, segmentação e paginação.
Memória virtual
Como apontou @Daniel R Hicks em outra resposta, os sistemas operacionais usam memória virtual. O que isso significa é que os aplicativos realmente não operam em endereços de memória reais, mas aqueles fornecidos pelo sistema operacional.
Essa técnica permite que o sistema operacional mova alguns dados da RAM para o chamado arquivo de paginação (Windows) ou Swap (* NIX). O HDD tem algumas magnitudes mais lentas que a RAM, mas não é um problema sério para os dados raramente acessados e permite que o sistema operacional forneça mais RAM às aplicações do que você realmente instalou.
Paginação
O que estávamos falando até agora é chamado de esquema de endereçamento plano.
Paginação é um esquema de endereçamento alternativo que permite endereçar mais memória que você normalmente poderia com uma palavra de máquina no modelo plano.
Imagine um livro cheio de palavras de quatro letras. Vamos dizer que existem 1024 números em cada página. Para endereçar um número, você precisa saber duas coisas:
- O número da página em que essa palavra é impressa.
- Qual palavra nessa página é a que você está procurando.
Agora é exatamente assim que as modernas CPUs x86 lidam com a memória. Está dividido em 4 páginas KiB (1024 palavras de máquina cada) e essas páginas têm números. (na verdade, as páginas também podem ser 4 MiB grandes ou 2 MiB com PAE). Quando você quiser endereçar a célula de memória, você precisa do número da página e do endereço nessa página. Note que cada célula da memória é referenciada por exatamente um par de números, que não será o caso da segmentação.
Segmentação
Bem, este é bastante semelhante ao paging. Foi usado na Intel 8086, apenas para citar um exemplo. Grupos de endereços agora são chamados de segmentos de memória, não de páginas. A diferença é que os segmentos podem se sobrepor e eles se sobrepõem muito. Por exemplo, em 8086 a maioria das células de memória estava disponível a partir de 4096 segmentos diferentes.
Um exemplo:
Vamos supor que temos 8 bytes de memória, todos contendo zeros, exceto o 4º byte, que é igual a 255.
Ilustração para o modelo de memória plana:
_____ | 0 | | 0 | | 0 | | 255 | | 0 | | 0 | | 0 | | 0 | -----
Ilustração para memória paginada com páginas de 4 bytes:
PAGE0 _____ | 0 | | 0 | | 0 | PAGE1 | 255 | _____ ----- | 0 | | 0 | | 0 | | 0 | -----
Ilustração para memória segmentada com segmentos de 4 bytes deslocados por 1:
SEG 0 ____ SEG 1 | 0 | _____ SEG 2 | 0 | | 0 | _____ SEG 3 | 0 | | 0 | | 0 | _____ SEG 4 | 255 | | 255 | | 255 | | 255 | _____ SEG 5 ----- | 0 | | 0 | | 0 | | 0 | _____ SEG 6 ----- | 0 | | 0 | | 0 | | 0 | _____ SEG 7 ----- | 0 | | 0 | | 0 | | 0 | _____ ----- | 0 | | 0 | | 0 | | 0 | ----- ----- ----- -----
Como você pode ver, o 4º byte pode ser endereçado de quatro maneiras: (endereçamento de 0)
- Segmento 0, deslocamento 3
- Segmento 1, deslocamento 2
- Segmento 2, deslocamento 1
- Segmento 3, offset 0
É sempre a mesma célula de memória.
Em implementações da vida real, os segmentos são deslocados em mais de 1 byte (para 8086 eram 16 bytes).
O que é ruim em segmentação é que é complicado (mas eu acho que você já sabe disso;) O que é bom, é que você pode usar algumas técnicas inteligentes para criar programas modulares.
Por exemplo, você pode carregar algum módulo em um segmento, depois fingir que o segmento é menor do que realmente é (apenas pequeno o suficiente para segurar o módulo) e escolher o primeiro segmento que não se sobreponha àquele pseudo-menor módulo e assim por diante. Basicamente, o que você consegue é páginas de tamanho variável.
Tem algo a acrescentar à explicação? Soe fora nos comentários. Quer ler mais respostas de outros usuários do Stack Exchange com experiência em tecnologia? Confira o tópico de discussão completo aqui.