Eu tenho uma pergunta conceitual: o que significa "alta" densidade de código? e por que isso é tão importante?
fonte
Eu tenho uma pergunta conceitual: o que significa "alta" densidade de código? e por que isso é tão importante?
A densidade de código refere-se livremente a quantas instruções de microprocessador são necessárias para executar uma ação solicitada e quanto espaço cada instrução ocupa. De um modo geral, quanto menos espaço uma instrução ocupa e mais trabalho por instrução que um microprocessador pode executar, mais denso é o código.
Percebo que você marcou sua pergunta com a tag 'arm'; Eu posso ilustrar a densidade do código usando as instruções do ARM.
Digamos que você deseja copiar um bloco de dados de um lugar na memória para outro. Conceitualmente, seu código de alto nível seria algo como isto:
void memcpy(void *dest, void *source, int count_bytes)
{
char *s, *d;
s = source; d = dest;
while(count_bytes--) { *d++ = *s++; }
}
Agora, um compilador simples para um microprocessador simples pode converter isso em algo como o seguinte:
movl r0, count_bytes
movl r1, s
movl r2, d
loop: ldrb r3, [r1]
strb [r2], r3
movl r3, 1
add r1, r3
add r2, r3
sub r0, r3
cmp r0, 0
bne loop
(meu braço está um pouco enferrujado, mas você entendeu)
Agora, esse seria um compilador muito simples e um microprocessador muito simples, mas você pode ver no exemplo que examinamos 8 instruções por iteração do loop (7 se movermos o '1' para outro registro e mover a carga fora do loop). Isso não é realmente denso. A densidade do código também afeta o desempenho; se seus loops forem mais longos porque o código não é denso, talvez seja necessário mais cache de instruções para manter o loop. Mais cache significa um processador mais caro, mas, novamente, a decodificação complexa de instruções significa mais transistores para decifrar a instrução solicitada, por isso é um problema de engenharia clássico.
O ARM é muito bom a esse respeito. Todas as instruções podem ser condicionais, a maioria das instruções pode aumentar ou diminuir o valor dos registradores, e a maioria das instruções pode opcionalmente atualizar os sinalizadores do processador. No ARM e com um compilador moderadamente útil, o mesmo loop pode ser algo como isto:
movl r0, count_bytes
movl r1, s
movl r2, d
loop: ldrb r3, [r1++]
strb [r2++], r3
subs r0, r0, 1
bne loop
Como você pode ver, o loop principal é agora de 4 instruções. O código é mais denso porque cada instrução no loop principal faz mais. Isso geralmente significa que você pode fazer mais com uma determinada quantidade de memória, porque menos dela é usada para descrever como executar o trabalho.
Agora, o código ARM nativo costumava ter a reclamação de que não era super denso; isso se deve a duas razões principais: primeiro, 32 bits é uma instrução terrivelmente "longa"; portanto, muitos bits parecem desperdiçados em instruções mais simples; segundo, o código ficou inchado devido à natureza do ARM: todas as instruções são 32 bits longos, sem exceção. Isso significa que há um grande número de valores literais de 32 bits que você não pode carregar apenas em um registro. Se eu quisesse carregar "0x12345678" no r0, como codificaria uma instrução que não apenas continha 0x12345678, mas também descrevesse "carregar literal para r0"? Não há bits sobrando para codificar a operação real. A instrução literal de carregamento do ARM é uma pequena fera interessante, e o montador do ARM também deve ser um pouco mais inteligente do que os montadores normais, porque precisa "capturar"
De qualquer forma, para responder a essas reclamações, o ARM surgiu com o modo Thumb. Em vez de 32 bits por instrução, o comprimento da instrução agora é de 16 bits para quase todas as instruções e 32 bits para ramificações. Houve alguns sacrifícios no modo Thumb, mas, em geral, esses sacrifícios eram fáceis de fazer porque o Thumb proporcionou algo como uma melhoria de 40% na densidade do código, apenas reduzindo o comprimento das instruções.
A "densidade de código" de um conjunto de instruções é uma medida de quanto você pode obter em uma determinada quantidade de memória de programa ou quantos bytes de memória de programa você precisa para armazenar uma determinada quantidade de funcionalidade.
Como Andrew Kohlsmith apontou, mesmo no mesmo MCU, diferentes compiladores podem obter diferentes densidades de código.
Você pode ler "Insetos do mundo dos computadores", de Miro Samek, que compara uma variedade de MCUs.
fonte