¿Cómo funciona el modificador de tipo de registro en diferentes arquitecturas de CPU?

2

Esta pregunta es para aclarar mis dudas sobre esta clase de almacenamiento de registros.

  1. cuando una variable está calificada para el registro, el compilador coloca la variable en un registro de la CPU que no sea RAM para facilitar el acceso. ¿Entonces hay registros disponibles en una CPU para fines generales (permite que el usuario la use libremente)? (No voy a preguntar si significa SFR (no me gusta cambiar el significado de SFR)

    En una MCU PIC (tal vez aplicable solo a la línea de base) los SFR y los registros de propósito general (que es la única RAM que creo) existen juntos. Aquí no puedo pensar en ninguna optimización con un 'registro' o hay?

  2. ¿Alguien podría explicar cómo logra la optimización en términos de velocidad (de acceso) en otras arquitecturas?

  3. ¿O las preguntas anteriores de todos los conceptos erróneos?

pregunta raforanz

5 respuestas

3

Tu pregunta es un poco confusa, pero quizás esto ayude a aclararla.

Hay dos áreas a considerar:

  • si el núcleo de ejecución puede operar directamente en elementos en la memoria
  • la velocidad de las operaciones en la memoria

Pequeños microcontroladores integrados

Estos pequeños microcontroladores no tienen RAM externa. Toda la RAM es interna, pero parte de ella se usa para cosas específicas como registros.

Por ejemplo, los PIC de Microchip que mencionas tienen un registro "W". Esto es solo en la RAM normal como en todo lo demás, pero las instrucciones con dos operandos generalmente requieren que uno de ellos esté en el registro W.

Esto simplifica enormemente el diseño del microcontrolador en el nivel de la electrónica y mantiene bajos los costos / la energía. También tiene otros beneficios, como el tiempo predecible (en ciclos) para las instrucciones.

Es por esto que verá instrucciones que cargan W con un valor, lo operan y luego lo vuelven a copiar de W a otra parte en la memoria. El compilador usa el registro porque tiene que hacerlo.

Procesadores más grandes

Otros procesadores (CPU) como x86 / 64 tienen RAM externa, lo cual es una gran diferencia. Observe que ahora un "registro" significa algo muy diferente porque tenemos diferentes tipos de memoria.

Externo a la CPU es una gran cantidad de RAM, interna a la CPU es un número de bloques de memoria más pequeños. Algunos de estos son registros de almacenamiento que contienen una cantidad de datos, generalmente igual al ancho de datos de la arquitectura. Por lo tanto, para un procesador Intel de 32 bits, los registros (como EAX, EBX, etc.) tienen un ancho de 32 bits.

Estos procesadores tienen instrucciones más complicadas que a menudo pueden operar en registros o en RAM externa. Los datos para una instrucción no siempre tienen que estar en un registro. Por lo tanto, ¿por qué nos molestaríamos? La respuesta es la velocidad. Cuando hay una opción, el compilador utilizará registros para reducir el tiempo de ejecución.

Estos complicados procesadores tienen diferentes tiempos de acceso para diferentes tipos de memoria. Los registros que están en el dado de la CPU son muy rápidos de acceder. Por lo tanto, si tiene una variable que está en uso constante en algún código, tiene sentido cargarla en un registro, operarla repetidamente y luego volver a copiarla en la RAM externa cuando termine.

    
respondido por el David
4

El "registro" de AFAIK es solo una recomendación muy general para el compilador; no significa que el compilador tiene para colocar la variable en un registro. La mayoría de las veces, el compilador sabe dónde colocar la variable y, de todos modos, utiliza registros donde sea posible. Muy a menudo la palabra clave no tiene efecto.

No conozco los detalles internos de las MCU PIC pero en general los procesadores tienen un número limitado de registros que pueden usar para las operaciones (por ejemplo, la adición). Si una función utiliza muchas variables locales, no todas pueden mantenerse en registros y al menos algunas deben ubicarse en la RAM externa. El compilador tiene una estrategia sofisticada para determinar qué variables se deben mantener en los registros (por ejemplo, las que se usan con más frecuencia) y cuáles no (por ejemplo, las que deben estar en la memoria de todos modos porque son referenciadas por los punteros).

    
respondido por el Curd
1

Dependería de qué compilador se use, pero tienes razón; para un procesador que no tiene nada más que registros, con el tiempo de acceso sin cambios sin importar qué registro (sin selección de banco), entonces la calificación debería no tener sentido.

Si se necesita la selección del banco, entonces el compilador debería limitar la variable al mismo banco que se usa actualmente en el momento de la ejecución.

Pero ¿por qué especular? Puede verificar esto comparando el ensamblaje y la salida del código de máquina del compilador, con y sin una calificación de registro en un lugar interesante. Si no ve ninguna diferencia, sabe que la calificación no es necesaria actualmente. Sin embargo, no significa que no será útil más tarde.

(Puede usar programas de detección de diferencias, actuando en la salida del ensamblaje. Exactamente qué programas usar depende de su preferencia. Yo usaría diff o meld en Linux, por ejemplo).

    
respondido por el James Cameron
1

Dependiendo del procesador, el acceso a los datos en los registros puede realizarse con una instrucción más corta que el acceso a los datos en la memoria. Solo eso puede acelerar la ejecución de esa instrucción, además de guardar la memoria del programa. La ganancia de velocidad puede ser especialmente beneficiosa dentro de un bucle. Algunas operaciones solo pueden funcionar en un registro o entre dos registros. Tener una variable en un registro en ese momento es una necesidad. Si se puede mantener en el registro, se pueden guardar dos operaciones (cargar el registro de la memoria y guardar el nuevo valor en la memoria). La mayoría de los compiladores son mejores y más exhaustivos que la mayoría de los programadores para averiguar cuál es la mejor manera de beneficiarse utilizando el número limitado de registros para este propósito. Examine la salida del ensamblador del mismo código sin especificadores de register , compilados con y sin la optimización activada para ver qué hace el optimizador y qué no asigna a los registros.

    
respondido por el JRobert
0

Hoy en día, muchos compiladores tienen algoritmos de análisis de flujo de datos que pueden usar los registros de manera más eficiente de lo que sería posible si un programador experto colocara cada variable en un registro o en la memoria, ya que los compiladores pueden decidir que las variables deben vivir en registros para algunos. Partes de su vida y en memoria para otras partes. Como tal, la función principal de la palabra clave de registro es indicar al compilador que debe prohibir cualquier intento de tomar la dirección de una variable en particular. Tomar la dirección de una variable generalmente implica que no se debe mantener en un registro entre llamadas a funciones, pero para las variables cuya dirección no se toma, la palabra clave register no tiene ningún efecto cuando el compilador decide cuándo mantener las variables en los registros .

    
respondido por el supercat

Lea otras preguntas en las etiquetas