Pregunta

Tengo una pregunta básica sobre el montaje.

¿Por qué nos molestamos en hacer operaciones aritméticas sólo en registros si pueden trabajar en la memoria, así?

Por ejemplo ambos de los siguientes causa (esencialmente) el mismo valor que se calcula como una respuesta:

Fragmento 1

.data
    var dd 00000400h

.code

    Start:
        add var,0000000Bh
        mov eax,var
        ;breakpoint: var = 00000B04
    End Start


Fragmento 2

.code

    Start:
        mov eax,00000400h
        add eax,0000000bh
        ;breakpoint: eax = 0000040B
    End Start


 Por lo que puedo ver la mayoría de los textos y tutoriales hacer operaciones aritméticas sobre todo en un registro. ¿Es sólo más rápido al trabajo con registros?

Edit: Eso fue rápido:)

se les dio un par de grandes respuestas; mejor respuesta fue elegido en base a la primera respuesta satisfactoria.

¿Fue útil?

Solución

Los registros son mucho más rápidos y también las operaciones que se pueden realizar directamente en la memoria son mucho más limitadas.

Otros consejos

Si nos fijamos en las arquitecturas de computadora, se encuentra una serie de niveles de memoria. Los que están cerca de la CPU son el ayuno, caro (por un momento), y por lo tanto pequeña, mientras que en el otro extremo tiene dispositivos de memoria grandes, lentas y barato. En una computadora moderna, es decir, normalmente algo como:

 CPU registers (slightly complicated, but in the order of 1KB per a core - there
                are different types of registers. You might have 16 64 bit
                general purpose registers plus a bunch of registers for special
                purposes)
 L1 cache (64KB per core)
 L2 cache (256KB per core)
 L3 cache (8MB)
 Main memory (8GB)
 HDD (1TB)
 The internet (big)

Con el tiempo, más y más niveles de caché se han añadido - lo que puedo recordar un momento en que las CPU no tiene ningún cachés a bordo, y ni siquiera estoy viejo! En estos días, los discos duros vienen con memorias caché de a bordo, y el Internet se almacenan en caché en cualquier número de lugares:. En la memoria, en el disco duro, y tal vez en el almacenamiento en caché de los servidores proxy

Hay un dramático (a menudo órdenes de magnitud) disminución en ancho de banda y aumento en latencia en cada paso de la CPU. Por ejemplo, un disco duro podría ser capaz de ser leído en 100 MB / s con una latencia de 5 ms (estas cifras pueden no ser exactamente correcto), mientras que la memoria principal se puede leer a 6,4 GB / s con una latencia de 9ns (seis órdenes de ¡magnitud!). La latencia es un factor muy importante, ya que no desea mantener la CPU esperar más de lo que tiene que (esto es especialmente cierto para las arquitecturas con tuberías profundas, pero eso es una discusión para otro día).

La idea es que a menudo se le vuelve a utilizar los mismos datos una y otra vez, así que tiene sentido para ponerlo en una pequeña memoria caché rápida para operaciones posteriores. Esto se conoce como temporal localidad . Otro principio importante de la localidad es espacial localidad , que dice que las posiciones de memoria cerca unos de otros es probable que se leen más o menos al mismo tiempo. Es por esta razón que la lectura de la memoria RAM hará que un bloque más grande de memoria RAM para leer y poner en caché en la CPU. Si no fuera por estos principios de la localidad, entonces cualquier ubicación en la memoria tendría una oportunidad igual probabilidad de ser leído en cualquier momento uno, por lo que no habría manera de predecir lo que va a acceder siguiente, y todos los niveles de caché en el mundo no va a mejorar la velocidad. Es lo mismo que sólo tiene que utilizar un disco duro, pero estoy seguro de que sabes lo que es tener el equipo llega a un punto muerto cuando la paginación (que básicamente está utilizando el disco duro como una extensión de la memoria RAM). Es conceptualmente posible no tener memoria a excepción de una unidad de disco duro (y muchos dispositivos pequeños tienen una única memoria), pero esto sería muy lento en comparación con lo que estamos familiarizados.

Otra de las ventajas de tener registros (y sólo un pequeño número de registros) es que le permite tener Instrucciones más cortas . Si usted tiene instrucciones que contienen dos (o más) de 64 direcciones de bit, que va a tener algunas instrucciones largas!

se accede a los Registros manera rápido que la memoria RAM, ya que no tiene que acceder al bus de memoria "lento"!

86, al igual que casi todos los demás CPU "normal", se podría aprender de montaje para, es un registro " máquina ". Hay otras maneras de diseñar algo que se puede programar (por ejemplo, una máquina de Turing que se mueve a lo largo de una "cinta" lógico en la memoria), pero las máquinas registro han demostrado ser básicamente el único camino a seguir para un alto rendimiento.

Desde 86 fue diseñado para registros de uso, realmente no se puede evitar por completo, incluso si se quería y no le importaba sobre el rendimiento.

Current CPU x86 puede leer / escribir muchos más registros por ciclo de reloj de posiciones de memoria.

Por ejemplo, Intel Skylake puede hacer dos cargas y una tienda de / a su 32kiB 8 vías asociativo caché L1D por ciclo (mejor de los casos), pero puede leer más de 10 registros por ciclo de reloj, y escribir 3 o 4 (más EFLAGS) .

La construcción de un caché L1D con tantos puertos de lectura / escritura como el archivo de registro sería prohibitivamente caro (en el transistor recuento / área y el uso de energía), sobre todo si se quería mantenerlo tan grande como lo es. Es probable que sólo no es físicamente posible construir algo que se puede utilizar la memoria los registros de los usos manera x86 con el mismo rendimiento.

Además, escribir un registro y luego leerlo de nuevo tiene esencialmente cero latencia ya que la CPU detecta y envía el resultado directamente desde la salida de una unidad de ejecución a la entrada de otro, sin pasar por la etapa de escritura no simultánea. (Ver https://en.wikipedia.org/wiki/Classic_RISC_pipeline#Solution_A._Bypassing ).

Estas conexiones resultado de reenvío entre unidades de ejecución se denominan "red de bypass" o "red de traslado", y es mucho más fácil para la CPU para hacer esto para un diseño de registro que si todo lo que tenía que entrar en la memoria y volver atrás. La CPU sólo tiene que comprobar un número de registro de 3 a 5 bits, en lugar de una dirección de 32 bits o de 64 bits, para detectar los casos donde se requiere la salida de una instrucción de inmediato como la entrada para otra operación. (Y esos números de registro están en forma fija en la máquina de código, para que estén disponibles de inmediato.)

Como otros han mencionado, 3 ó 4 bits para hacer frente a un registro hacen que el formato de código de máquina mucho más compacto que si cada instrucción tenía direcciones absolutas.


https://en.wikipedia.org/wiki/Memory_hierarchy : se puede pensar en los registros como un pequeño rápido de tamaño fijo espacio de memoria independiente de la memoria principal, donde se admite el direccionamiento absoluto solamente directa. (Puede no "índice" de un registro:. N dado un número entero en un registro, no se puede obtener el contenido del registro Nth con una insn)

Los registros también son privados de un solo núcleo de la CPU, así que fuera de orden de ejecución puede hacer lo que quiera con ellos. Con la memoria, tiene que preocuparse de lo que ordenar las cosas se hacen visibles a otros núcleos de CPU.

Tener un número fijo de registros es parte de lo que vamos a hacer CPUs register-cambiar el nombre de la ejecución fuera de orden. Tener el número de registro disponible de inmediato cuando se decodifica una instrucción también hace que esto sea más fácil:. Nunca hay una lectura o escritura en un registro que aún no es conocido

Consulte ¿por qué mulss toman sólo 3 ciclos en Haswell, diferentes de tablas de instrucciones de Agner? para una explicación de register el cambio de nombre, y un ejemplo específico (las ediciones posteriores a la pregunta / partes posteriores de mi respuesta que muestran el aumento de velocidad de desenrollado con varios acumuladores para ocultar la latencia FMA a pesar de que vuelve a utilizar el mismo registro arquitectónico repetidamente).


La memoria intermedia de almacenamiento con la tienda de reenvío no le dan básicamente "el cambio de nombre de memoria". Una tienda / recarga a una posición de memoria es independiente de las tiendas anteriores y la carga a ese lugar desde el interior de este núcleo.

Las repetidas llamadas a funciones con una pila-args convención de llamada, y / o devolver un valor por referencia, son los casos en que los mismos bytes de memoria de pila pueden ser reutilizados varias veces.

Los segundos almacenan / recarga puede ejecutar incluso si la primera tienda está a la espera de sus entradas. (He probado esto en Skylake, pero IDK si alguna vez publicado los resultados en un cualquier respuesta.)

Utilizamos registros porque son rápidos. Por lo general, operan a la velocidad de la CPU.
Registros y caché de la CPU se hacen con diferentes telas y tecnología /
son caros. RAM en el otro lado es barato y 100 veces más lento.

En términos generales aritmética de registros es mucho más rápido y mucho preferido. Sin embargo, hay algunos casos en que la aritmética directo a memoria es útil. Si todo lo que quiere hacer es un incremento en el número de memoria (y nada más, al menos por unos pocos millones de instrucciones) entonces una sola instrucción aritmética directo a la memoria suele ser ligeramente más rápido que la carga / add / tienda.

Además, si se realizan operaciones complejas de matriz por lo general necesita una gran cantidad de registros para realizar un seguimiento de dónde se encuentra y donde terminan sus matrices. En arquitecturas de mayor edad podría ejecutar fuera de registro muy rápido por lo que la opción de añadir dos bits de memoria juntos sin zapping cualquiera de sus registros actuales fue muy útil.

Sí, es mucho mucho mucho más rápido a los registros de uso. Incluso si sólo tenemos en cuenta la distancia física desde el procesador para registrar en comparación con proc para la memoria, se ahorra mucho tiempo al no enviar electrones hasta el momento, y eso significa que puede correr a una velocidad de reloj más alta.

Sí - también normalmente se puede empujar / pop registros fácilmente para llamar procedimientos, manejo de interrupciones, etc.

Es que el conjunto de instrucciones no le permiten hacer este tipo de operaciones complejas:

add [0x40001234],[0x40002234]

Tienes que ir a través de los registros.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top