Pergunta

Os processadores de 32 bits da Intel, como o Pentium, possuem barramento de dados de 64 bits e, portanto, buscam 8 bytes por acesso. Com base nisso, suponho que os endereços físicos que esses processadores emitem no barramento de endereço sejam sempre múltiplos de 8.

Em primeiro lugar, essa conclusão está correta?

Em segundo lugar, se estiver correto, deve -se alinhar membros da estrutura de dados em um limite de 8 bytes. Mas eu vi pessoas usando um alinhamento de 4 bytes nesses processadores.

Como eles podem ser justificados ao fazê -lo?

Foi útil?

Solução

A regra geral usual (diretamente dos manuais de otimização da Intels e da AMD) é que todo tipo de dados deve ser alinhado por seu próprio tamanho. Um int32 deve estar alinhado em um limite de 32 bits, um int64 em um limite de 64 bits, e assim por diante. Um char vai se encaixar muito bem em qualquer lugar.

Outra regra geral é, é claro, "o compilador foi informado sobre os requisitos de alinhamento". Você não precisa se preocupar com isso, porque o compilador sabe adicionar o preenchimento e compensações corretas para permitir acesso eficiente aos dados.

A única exceção é ao trabalhar com instruções SIMD, onde você deve garantir manualmente o alinhamento na maioria dos compiladores.

Em segundo lugar, se estiver correto, deve -se alinhar membros da estrutura de dados em um limite de 8 bytes. Mas eu vi pessoas usando um alinhamento de 4 bytes nesses processadores.

Não vejo como isso faz a diferença. A CPU pode simplesmente emitir uma leitura para o bloco de 64 bits que contém esses 4 bytes. Isso significa que recebe 4 bytes extras antes dos dados solicitados ou depois dele. Mas em ambos os casos, é preciso apenas uma única leitura. O alinhamento de 32 bits de dados de 32 bits garante que eles não cruzem um limite de 64 bits.

Outras dicas

O ônibus físico é de 64 bits ... múltiplo de 8 -> sim

No entanto, há mais dois fatores a serem considerados:

  1. Alguns conjuntos de instruções X86 são abordados. Alguns estão alinhados com 32 bits (é por isso que você tem 4 byte). Mas nenhuma instrução (núcleo) está alinhada 64 bits. A CPU pode lidar com o acesso de dados desalinhados.
  2. Se você se preocupa com o desempenho, pense na linha de cache, não na memória principal. As linhas de cache são muito mais largas.

Eles são justificados ao fazê-lo porque mudar para o alinhamento de 8 bytes constituiria uma mudança de ABI, e a melhoria marginal de desempenho não vale o problema.

Como alguém já disse, as cachelines são importantes. Todos os acessos no barramento de memória real são em termos de linhas de cache (64 bytes no x86, IIRC). Veja o documento "o que todo programador precisa saber sobre a memória" que já foi mencionado. Portanto, o tráfego de memória real está alinhado em 64 bytes.

Para acesso aleatório e, desde que os dados não estejam desalinhados (por exemplo, cruzando um limite), não acho que isso importa muito; O endereço e o deslocamento corretos nos dados podem ser encontrados com uma construção simples e construída em hardware. Fica lento quando um acesso de leitura não é suficiente para obter um valor. É também por isso que os compiladores geralmente colocam valores pequenos (bytes etc.), porque não precisam estar em um deslocamento específico; Os shorts devem estar em endereços uniformes, 32 bits em endereços de 4 bytes e 64 bits em endereços de 8 bytes.

Observe que, se você tiver o cache envolvido e o acesso de dados lineares, as coisas serão diferentes.

O barramento de 64 bits que você se refere aos Feeds os caches. Como CPU, sempre leia e escreva linhas de cache inteiras. O tamanho de uma linha de cache é sempre um múltiplo de 8, e seu endereço físico está realmente alinhado em 8 compensações de bytes.

As transferências de cache para registrar não usam o banco de dados externo; portanto, a largura desse barramento é irrelevante.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top