Réponses:
La densité de code fait vaguement référence au nombre d'instructions de microprocesseur nécessaires pour effectuer une action demandée et à l'espace occupé par chaque instruction. D'une manière générale, moins une instruction prend de place et plus un microprocesseur peut travailler par instruction, plus son code est dense.
Je remarque que vous avez marqué votre question avec la balise «arm»; Je peux illustrer la densité du code à l'aide des instructions ARM.
Supposons que vous souhaitiez copier un bloc de données d'un endroit en mémoire à un autre. Conceptuellement, votre code de haut niveau ressemblerait à ceci:
void memcpy(void *dest, void *source, int count_bytes)
{
char *s, *d;
s = source; d = dest;
while(count_bytes--) { *d++ = *s++; }
}
Maintenant, un simple compilateur pour un microprocesseur simple peut convertir cela en quelque chose comme ceci:
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
(mon bras est un peu rouillé, mais vous avez l'idée)
Maintenant, ce serait un compilateur très simple et un microprocesseur très simple, mais vous pouvez voir dans l'exemple que nous examinons 8 instructions par itération de la boucle (7 si nous déplaçons le «1» vers un autre registre et déplaçons la charge hors de la boucle). Ce n'est pas vraiment dense du tout. La densité du code affecte également les performances; si vos boucles sont plus longues car le code n'est pas dense, vous devrez peut-être plus de cache d'instructions pour maintenir la boucle. Plus de cache signifie un processeur plus cher, mais là encore, le décodage d'instructions complexes signifie plus de transistors pour déchiffrer l'instruction demandée, c'est donc un problème d'ingénierie classique.
ARM est plutôt sympa à cet égard. Chaque instruction peut être conditionnelle, la plupart des instructions peuvent incrémenter ou décrémenter la valeur des registres, et la plupart des instructions peuvent éventuellement mettre à jour les drapeaux du processeur. Sur ARM et avec un compilateur moyennement utile, la même boucle peut ressembler à ceci:
movl r0, count_bytes
movl r1, s
movl r2, d
loop: ldrb r3, [r1++]
strb [r2++], r3
subs r0, r0, 1
bne loop
Comme vous pouvez le voir, la boucle principale est désormais composée de 4 instructions. Le code est plus dense car chaque instruction de la boucle principale en fait plus. Cela signifie généralement que vous pouvez faire plus avec une quantité de mémoire donnée, car elle est moins utilisée pour décrire comment effectuer le travail.
Désormais, le code ARM natif se plaignait souvent qu'il n'était pas super-dense; cela est dû à deux raisons principales: premièrement, 32 bits est une instruction terriblement "longue", donc beaucoup de bits semblent être gaspillés pour des instructions plus simples, et deuxièmement, le code s'est gonflé en raison de la nature d'ARM: chaque instruction est 32 bits de long, sans exception. Cela signifie qu'il existe un grand nombre de valeurs littérales 32 bits que vous ne pouvez pas simplement charger dans un registre. Si je voulais charger "0x12345678" dans r0, comment coder une instruction qui contient non seulement 0x12345678, mais décrit également "charger littéralement vers r0"? Il ne reste aucun bit pour coder l'opération réelle. L'instruction littérale de chargement ARM est une petite bête intéressante, et l'assembleur ARM doit également être un peu plus intelligent que les assembleurs normaux, car il doit "attraper"
Quoi qu'il en soit, pour répondre à ces plaintes, ARM a proposé le mode Thumb. Au lieu de 32 bits par instruction, la longueur de l'instruction est désormais de 16 bits pour presque toutes les instructions et de 32 bits pour les branches. Il y a eu quelques sacrifices avec le mode Thumb, mais dans l'ensemble, ces sacrifices ont été faciles à faire parce que Thumb vous a apporté quelque chose comme une amélioration de 40% de la densité de code simplement en réduisant la longueur des instructions.
La «densité de code» d'un jeu d'instructions est une mesure de la quantité de choses que vous pouvez entrer dans une quantité donnée de mémoire de programme, ou du nombre d'octets de mémoire de programme dont vous avez besoin pour stocker une quantité donnée de fonctionnalité.
Comme l'a souligné Andrew Kohlsmith, même sur le même MCU, différents compilateurs peuvent obtenir une densité de code différente.
Vous aimerez peut-être lire "Insectes du monde informatique" de Miro Samek, qui compare une variété de microcontrôleurs.