Sobre la densidad del código y su definición

Respuestas:

24

La densidad de código se refiere libremente a cuántas instrucciones de microprocesador se necesitan para realizar una acción solicitada, y cuánto espacio ocupa cada instrucción. En términos generales, cuanto menos espacio ocupa una instrucción y más trabajo por instrucción que puede hacer un microprocesador, más denso es su código.

Me doy cuenta de que has etiquetado tu pregunta con la etiqueta 'brazo'; Puedo ilustrar la densidad del código usando las instrucciones ARM.

Supongamos que desea copiar un bloque de datos de un lugar en la memoria a otro. Conceptualmente, su código de alto nivel se vería así:

void memcpy(void *dest, void *source, int count_bytes)
{
    char *s, *d;

    s = source; d = dest;
    while(count_bytes--) { *d++ = *s++; }
}

Ahora, un compilador simple para un microprocesador simple puede convertir esto en algo como lo siguiente:

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

(mi BRAZO está un poco oxidado, pero entiendes la idea)

Ahora, este sería un compilador muy simple y un microprocesador muy simple, pero puedes ver en el ejemplo que estamos viendo 8 instrucciones por iteración del ciclo (7 si movemos el '1' a otro registro y movemos la carga fuera del circuito). Eso no es realmente denso en absoluto. La densidad del código también afecta el rendimiento; Si sus bucles son más largos porque el código no es denso, es posible que necesite más caché de instrucciones para mantener el bucle. Más caché significa un procesador más costoso, pero una vez más, la decodificación de instrucciones compleja significa más transistores para descifrar la instrucción solicitada, por lo que es un problema de ingeniería clásico.

ARM es bastante agradable a este respecto. Cada instrucción puede ser condicional, la mayoría de las instrucciones pueden aumentar o disminuir el valor de los registros, y la mayoría de las instrucciones pueden actualizar opcionalmente los indicadores del procesador. En ARM y con un compilador moderadamente útil, el mismo bucle puede verse así:

movl r0, count_bytes
movl r1, s
movl r2, d
loop: ldrb r3, [r1++]
strb [r2++], r3
subs r0, r0, 1
bne loop

Como puede ver, el bucle principal ahora tiene 4 instrucciones. El código es más denso porque cada instrucción en el bucle principal hace más. Esto generalmente significa que puede hacer más con una cantidad dada de memoria, porque se usa menos para describir cómo realizar el trabajo.

Ahora el código ARM nativo a menudo tenía la queja de que no era súper denso; esto se debe a dos razones principales: primero, 32 bits es una instrucción terriblemente "larga", por lo que muchos bits parecen desperdiciarse para obtener instrucciones más simples, y segundo, el código se hinchó debido a la naturaleza de ARM: cada instrucción es 32 bits de largo, sin excepción. Esto significa que hay una gran cantidad de valores literales de 32 bits que no puede cargar en un registro. Si quisiera cargar "0x12345678" en r0, ¿cómo codifico una instrucción que no solo contenga 0x12345678, sino que también describa "cargar literal a r0"? No quedan bits para codificar la operación real. La instrucción literal de carga ARM es una pequeña bestia interesante, y el ensamblador ARM también debe ser un poco más inteligente que los ensambladores normales, porque tiene que "atrapar"

De todos modos, para responder a estas quejas, ARM creó el modo Pulgar. En lugar de 32 bits por instrucción, la longitud de la instrucción ahora es de 16 bits para casi todas las instrucciones y de 32 bits para las ramas. Hubo algunos sacrificios con el modo Thumb, pero en general estos sacrificios fueron fáciles de hacer porque Thumb le proporcionó algo así como una mejora del 40% en la densidad del código simplemente reduciendo la longitud de la instrucción.

akohlsmith
fuente
Excelente respuesta Realmente excelente
pingswept
No olvide mencionar Thumb2, que es una mejora aún mayor para la mayoría de las aplicaciones.
Yann Ramin el
Muy interesante lectura. Estoy aprendiendo mucho solo leyendo preguntas y respuestas en este sitio.
onaclov2000
Muchas gracias Andrew, excelente respuesta, me ayudó mucho con mis dudas :)
Quaremz
Esto también podría hacer con una breve mención de cómo la densidad de código se ve afectada por RISC frente a CISC (con RISC generalmente es más bajo que CISC ya que las arquitecturas CISC tienden a tener más instrucciones que pueden hacer más pero pueden resultar en tuberías más largas / complejas mientras RISC se centra en instrucciones más simples que permiten tuberías más simples, por lo tanto, la densidad del código RISC es menor
JAB
1

La "densidad de código" de un conjunto de instrucciones es una medida de la cantidad de cosas que puede obtener en una cantidad dada de memoria de programa, o cuántos bytes de memoria de programa necesita para almacenar una cantidad dada de funcionalidad.

Como Andrew Kohlsmith señaló, incluso en el mismo MCU, diferentes compiladores pueden obtener una densidad de código diferente.

Puede disfrutar leyendo "Insectos del mundo de la informática" de Miro Samek, que compara una variedad de MCU.

davidcary
fuente